public Decomposer(SteeringPipeline pipeline, NavMeshPathGraph navMesh, DynamicCharacter character) { Character = character; Pipeline = pipeline; aStarPathFinding = new NodeArrayAStarPathFinding(navMesh, new EuclideanDistanceHeuristic()); aStarPathFinding.NodesPerSearch = 150; }
public MovementOutput GetMovement(DynamicCharacter character, GlobalPath currentSmoothedSolution) { DynamicMovement output; output = new DynamicFollowPath(character.KinematicData, currentSmoothedSolution) { MaxAcceleration = 20.0f, PathOffset = 0.15f }; return output.GetMovement(); }
public void AddFlockMember(GameObject gameObject) { var member = new DynamicCharacter(gameObject) { Drag = this.Drag, MaxSpeed = this.MaximumSpeed }; member.KinematicData.velocity = new Vector3(Random.Range(0, this.MaximumSpeed), 0,Random.Range(0, this.MaximumSpeed)); member.Movement = this.GenerateBlendingMovementFor(member); this.FlockMembers.Add(member); }
// Use this for initialization void Awake() { this.draw = false; this.navMesh = NavigationManager.Instance.NavMeshGraphs[0]; this.character = new DynamicCharacter(this.characterAvatar) { Drag = DRAG, MaxSpeed = MAX_SPEED }; aStarPathFinding = new NodeArrayAStarPathFinding(this.navMesh, new EuclideanDistanceHeuristic()); aStarPathFinding.NodesPerSearch = 100; }
// Use this for initialization void Awake() { this.draw = false; this.navMesh = NavigationManager.Instance.NavMeshGraphs[0]; this.character = new DynamicCharacter(this.characterAvatar) { Drag = DRAG, MaxSpeed = MAX_SPEED }; this.bots = GameObject.FindGameObjectsWithTag("Bot"); this.decomposer = new Decomposer(new NodeArrayAStarPathFinding(this.navMesh, new EuclideanDistanceHeuristic())); this.decomposer.searchAlgorithm.NodesPerSearch = 100; }
public GlobalPath decompose(DynamicCharacter character, Goal goal) { this.aStarPathFinding.InitializePathfindingSearch(character.KinematicData.position, goal.position); if (this.aStarPathFinding.InProgress) { var finished = this.aStarPathFinding.Search(out this.currentSolution, true); if (finished && this.currentSolution != null) { //lets smooth out the Path this.currentSmoothedSolution = StringPullingPathSmoothing.SmoothPath(character.KinematicData, this.currentSolution); currentSmoothedSolution.CalculateLocalPathsFromPathPositions(character.KinematicData.position); return this.currentSmoothedSolution; } } return null; }
private List<DynamicCharacter> CloneSecondaryCharacters(GameObject objectToClone, int numberOfCharacters, GameObject[] obstacles) { var characters = new List<DynamicCharacter> (); for (int i = 0; i < numberOfCharacters; i++) { var clone = GameObject.Instantiate (objectToClone); //clone.transform.position = new Vector3(30,0,i*20); clone.transform.position = this.GenerateRandomClearPosition (obstacles); var character = new DynamicCharacter (clone) { MaxSpeed = MAX_SPEED, Drag = DRAG }; //character.KinematicData.orientation = (float)Math.PI*i; characters.Add (character); } return characters; }
public HumanActuator(DynamicCharacter character) { SeekMovement = new DynamicSeek { MaxAcceleration = 60f, Character = character.KinematicData, StopRadius = 49f // 49 = 7^2 }; this.Character = character; this.Character.MaxSpeed = 30f; FollowPathMovement = new DynamicFollowPath(character.KinematicData) { MaxAcceleration = 40f, MaxSpeed = 30f, SlowRadius = 3.5f, StopRadius = 3f, GoalPosition = GoalPosition }; }
protected MovementOutput GetOutput(GlobalPath suggestedPath, DynamicCharacter character) { DynamicMovement movement; if (suggestedPath != null) { SeekMovement.Target = new KinematicData() { position = suggestedPath.LocalPaths[0].EndPosition }; //Debug.DrawLine(character.KinematicData.position, SeekMovement.Target.position, Color.black); movement = SeekMovement; return movement.GetMovement(); } else { movement = FollowPathMovement; } return FilterMovementOutput(movement.GetMovement(), Character); }
public CarActuator(DynamicCharacter character) { SeekMovement = new DynamicSeek() { MaxAcceleration = 80f, Character = character.KinematicData, StopRadius = 49f // 49 = 7^2 }; this.Character = character; this.Character.BackingUp = false; //setting character MaxSpeed according to actuator this.Character.MaxSpeed = 40f; this.FollowPathMovement = new DynamicFollowPath(character.KinematicData) { MaxAcceleration = 60f, MaxSpeed = 50f, SlowRadius = 15f, StopRadius = 7f, GoalPosition = GoalPosition }; }
// Use this for initialization private void Awake() { this.draw = true; NavMeshPathGraph navMesh = NavigationManager.Instance.NavMeshGraphs[0]; this.character = new DynamicCharacter(this.characterAvatar); this.Pedestrians = new List<GameObject>(GameObject.FindGameObjectsWithTag("Pedestrian")).ConvertAll(p => new Pedestrian(p)); // Targeter TargeterComponent = new Targeter(this); // Decomposer DecomposerComponent = new Decomposer(this, navMesh, this.character); // TargetCollisionConstraint PathConstraints = new List<IConstraint>(); PathConstraints.Add(new PedestrianAvoidanceConstraint(this, character, this.Pedestrians)); PathConstraints.Add(new PathValidityCheckConstraint(this.character)); // Movement Constraints MovementConstraints = new List<IConstraint>(); StaticObstacleConstraint obsConstraint = new StaticObstacleConstraint(character) { AvoidMargin = 10f }; MovementConstraints.Add(obsConstraint); if (CharacterInUse.Equals(CharacterType.Car)) { Actuator = new CarActuator(this.character); } else if (CharacterInUse.Equals(CharacterType.Human)) { Actuator = new HumanActuator(this.character); } }
private void InitializeSecondaryCharacter(DynamicCharacter character, GameObject[] obstacles) { var priority = new PriorityMovement { Character = character.KinematicData }; foreach (var obstacle in obstacles) { //TODO: add your AvoidObstacle movement here //avoidObstacleMovement = new DynamicAvoidObstacle(obstacle) //{ // MaxAcceleration = MAX_ACCELERATION, // AvoidMargin = AVOID_MARGIN, // MaxLookAhead = MAX_LOOK_AHEAD, // Character = character.KinematicData, // MovementDebugColor = Color.magenta //}; //priority.Movements.Add(avoidObstacleMovement); } foreach (var otherCharacter in this.Characters) { if (otherCharacter != character) { //TODO: add your avoidCharacter movement here //var avoidCharacter = new DynamicAvoidCharacter(otherCharacter.KinematicData) //{ // Character = character.KinematicData, // MaxAcceleration = MAX_ACCELERATION, // AvoidMargin = AVOID_MARGIN, // MovementDebugColor = Color.cyan //}; //priority.Movements.Add(avoidCharacter); } } var straightAhead = new DynamicStraightAhead { Character = character.KinematicData, MaxAcceleration = MAX_ACCELERATION, MovementDebugColor = Color.yellow }; priority.Movements.Add(straightAhead); character.Movement = priority; }
// Use this for initialization void Awake() { this.draw = false; this.character = new DynamicCharacter(this.characterAvatar); this.character.Drag = 0.3f; this.people = new DynamicCharacter[this.peopleAvatar.Length]; for(int i = 0; i < this.peopleAvatar.Length;i++) { this.people[i] = new DynamicCharacter(this.peopleAvatar[i]); } var obstacles = GameObject.FindGameObjectsWithTag("Obstacle"); SteeringPipeline steeringPipeline = new SteeringPipeline(); steeringPipeline.Character = character.KinematicData; steeringPipeline.Targeters.Add(targeter = new TargetPosition()); steeringPipeline.Decomposers.Add(decomposerAStar = new NodeAStarDecomposer()); steeringPipeline.Constraints.Add( constraint = new ConstraitColisionWithWalls(obstacles, 500.0f) { AvoidMargin = 7f, MaxLookAhead = 7f, MaxWhiskersLookAhead = 5f }); steeringPipeline.Constraints.Add( constraint2 = new ConstraitColisionWithPeople(peopleAvatar, 15f) { }); steeringPipeline.Actuator = actuator = new PathFollowingActuator() { movement = new DynamicFollowPath() { MaxAcceleration = 40.0f, PathOffset = 0.05f, Movement = new DynamicCarSeek() { MaxSpeed = character.MaxSpeed, MinSpeed = 4f } }, SecondsToSmooth = 2f }; character.Movement = steeringPipeline; for (int i = 0; i < this.people.Length; i++) { SteeringPipeline personSteeringPipeline = new SteeringPipeline(); TargetPersonPosition personTargeter = new TargetPersonPosition(10.0f); personSteeringPipeline.Targeters.Add(personTargeter); DecomposerPersonPathCreation personDecomposer = new DecomposerPersonPathCreation(); personSteeringPipeline.Decomposers.Add(personDecomposer); personSteeringPipeline.Constraints.Add( constraint = new ConstraitColisionWithWalls(obstacles, 500.0f) { AvoidMargin = 7f, MaxLookAhead = 15f, MaxWhiskersLookAhead = 10f }); personSteeringPipeline.Actuator = personActuator = new PersonActuator() { movement = new DynamicFollowPath() { MaxAcceleration = 20.0f, PathOffset = 0.05f, Movement = new DynamicPedestrianSeek() }, }; personSteeringPipeline.Character = this.people[i].KinematicData; people[i].Movement = personSteeringPipeline; } StringPullingPathSmoothing.MinWidth = 10f; StringPullingPathSmoothing.MinDistanceToCharacter = 10f; }
public SteeringPipeline InitializeSteeringPipeline(DynamicCharacter orig, KinematicData dest) { //Pipeline SteeringPipeline pipe = new SteeringPipeline(orig.KinematicData) { MaxAcceleration = 15.0f }; //Targeter Targeter MouseClickTargeter = new Targeter() { Target = dest }; pipe.Targeters.Add(MouseClickTargeter); //Decomposer pathfindingDecomposer = new PathfindingDecomposer() { Graph = this.navMesh, Heuristic = new EuclideanDistanceHeuristic() }; pipe.Decomposers.Add(pathfindingDecomposer); //Actuator - Default: Car behaviour Actuator actuator = new CarActuator() { MaxAcceleration = 15.0f, Character = orig.KinematicData }; if (orig.GameObject.tag.Equals("Enemies")) { actuator = new TrollActuator() { MaxAcceleration = 10.0f, Character = orig.KinematicData }; } pipe.Actuator = actuator; //Constraints foreach (DynamicCharacter troll in enemies) { TrollConstraint trollConstraint = new TrollConstraint() { Troll = troll, margin = 1.0f }; pipe.Constraints.Add(trollConstraint); } MapConstraint mapConstraint = new MapConstraint() { chars = character, navMeshP = navMesh, margin = 1.0f }; pipe.Constraints.Add(mapConstraint); return pipe; }
// Use this for initialization void Awake() { this.draw = false; this.navMesh = NavigationManager.Instance.NavMeshGraphs[0]; this.character = new DynamicCharacter(this.characterAvatar); this.enemies = new List<DynamicCharacter>(); for (int i = 0; i < enemiesAvatar.Length; i++) { DynamicCharacter enemy = new DynamicCharacter(this.enemiesAvatar[i]); DynamicBackAndForth movement = new DynamicBackAndForth() { Character = enemy.KinematicData, MaxAcceleration = 10.0f, StopRadius = 2.0f, SlowRadius = 5.0f, MoveDistance = 25.0f }; movement.CalculatePositions(); enemy.Movement = movement; this.enemies.Add(enemy); } this.aStarPathFinding = new NodeArrayAStarPathFinding(this.navMesh, new EuclideanDistanceHeuristic()); this.aStarPathFinding.NodesPerSearch = 100; }
private void UpdateMovingGameObject(DynamicCharacter movingCharacter) { if (movingCharacter.Movement != null) { movingCharacter.Update(); movingCharacter.KinematicData.ApplyWorldLimit(X_WORLD_SIZE, Z_WORLD_SIZE); movingCharacter.GameObject.transform.position = movingCharacter.KinematicData.position; } }
public GlobalPath GetPath(DynamicCharacter character, GlobalPath partialSolution) { return StringPullingPathSmoothing.SmoothPath(character.KinematicData, partialSolution); }
private void InitializeSecondaryCharacter(DynamicCharacter character, GameObject[] obstacles) { var priority = new PriorityMovement { Character = character.KinematicData }; foreach (var obstacle in obstacles) { var avoidObstacleMovement = new DynamicAvoidObstacle(obstacle) { MaxAcceleration = MAX_ACCELERATION, avoidDistance = AVOID_MARGIN, lookAhead = MAX_LOOK_AHEAD, Character = this.RedCharacter.KinematicData, whiskersLookAhead = WHISKER_LOOK_AHEAD, MovementDebugColor = Color.magenta }; priority.Movements.Add(avoidObstacleMovement); } foreach (var otherCharacter in this.Characters) { if (otherCharacter != character) { //TODO: add your avoidCharacter movement here var avoidCharacter = new DynamicAvoidCharacter(otherCharacter.KinematicData) { Character = character.KinematicData, MaxAcceleration = MAX_ACCELERATION, AvoidMargin = AVOID_MARGIN, MaximumTimeLookAhead = MAX_TIME_AHEAD, MovementDebugColor = Color.cyan }; priority.Movements.Add(avoidCharacter); } } var straightAhead = new DynamicStraightAhead { Character = character.KinematicData, MaxAcceleration = MAX_ACCELERATION, MovementDebugColor = Color.yellow }; priority.Movements.Add(straightAhead); character.Movement = priority; }
protected abstract MovementOutput FilterMovementOutput(MovementOutput output, DynamicCharacter character);
private void InitializeCharacter(DynamicCharacter character, GameObject[] obstacles) { BlendedMovement Blended; Blended = new BlendedMovement { Character = character.KinematicData }; foreach (var obstacle in obstacles) { var avoidObstacleMovement = new DynamicAvoidObstacle() { MaxAcceleration = MAX_ACCELERATION, AvoidDistance = AVOID_MARGIN, LookAhead = MAX_LOOK_AHEAD, Character = character.KinematicData, Obstacle = obstacle, MovementDebugColor = Color.magenta }; Blended.Movements.Add(new MovementWithWeight(avoidObstacleMovement, (obstacles.Length + this.Flock.Count) * AVOIDOB)); } var DynamicSeparationMovement = new DynamicSeparation() { Character = character.KinematicData, MaxAcceleration = MAX_ACCELERATION, MovementDebugColor = Color.blue, Flock = this.Flock, SeparationFactor = FLOCK_SEPARATION_FACTOR, Radius = FLOCK_SEPARATION_RADIUS }; Blended.Movements.Add(new MovementWithWeight(DynamicSeparationMovement, (obstacles.Length + this.Flock.Count) * SEPARATIONB)); var DynamicCohesionMovement = new DynamicCohesion() { Character = character.KinematicData, MaxAcceleration = MAX_ACCELERATION, MovementDebugColor = Color.blue, Flock = this.Flock, FanAngle = FLOCK_COHESION_FAN_ANGLE, radius = FLOCK_COHESION_RADIUS }; Blended.Movements.Add(new MovementWithWeight(DynamicCohesionMovement, (obstacles.Length + this.Flock.Count) * COHESIONB)); var DynamicFlockVelocityMatchMovement = new DynamicFlockVelocityMatch() { Character = character.KinematicData, MaxAcceleration = MAX_ACCELERATION, MovementDebugColor = Color.blue, Flock = this.Flock, FanAngle = FLOCK_VELOCITYMATCHING_FAN_ANGLE, radius = FLOCK_VELOCITYMATCHING_RADIUS }; Blended.Movements.Add(new MovementWithWeight(DynamicFlockVelocityMatchMovement, (obstacles.Length + this.Flock.Count) * ALIGNB)); character.Movement = Blended; }
protected override MovementOutput FilterMovementOutput(MovementOutput output, DynamicCharacter character) { Vector3 charOrientation = MathHelper.ConvertOrientationToVector(character.KinematicData.orientation); float charSpeed = character.KinematicData.velocity.sqrMagnitude; float angleDiff = Mathf.Deg2Rad * (Vector3.Angle(charOrientation, output.linear)); float angleDiffAbs = Math.Abs(angleDiff); float distance = (GoalPosition - character.KinematicData.position).sqrMagnitude; if (character.BackingUp || angleDiffAbs >= MathConstants.MATH_PI - MathConstants.MATH_PI / 3f && charSpeed <= 1 && distance < 900f) // 900 = 30^2 { character.BackingUp = true; Vector3 contraryVector = MathHelper.ConvertOrientationToVector(MathHelper.ConvertVectorToOrientation((GoalPosition - character.KinematicData.position)) + MathConstants.MATH_PI); character.KinematicData.orientation = MathHelper.ConvertVectorToOrientation(Vector3.Lerp(charOrientation, contraryVector, 0.1f)); return output; } if (!character.BackingUp) { if (Physics.Raycast(character.KinematicData.position, character.KinematicData.velocity, 30f)) { //Debug.DrawLine(character.KinematicData.position, character.KinematicData.velocity.normalized*30f+character.KinematicData.position, Color.black); CapCharacterVelocity(character); } if (angleDiff > MathConstants.MATH_PI_2 / 6f && charSpeed >= 4900) // 4900 = 70^2 { output.linear = MathHelper.ConvertOrientationToVector(MathConstants.MATH_PI_2 / 6f).normalized; character.KinematicData.velocity = character.KinematicData.velocity.normalized * 40f; return output; } if (angleDiff > MathConstants.MATH_PI_2 / 3f && charSpeed >= 3600) // 3600 = 60^2 { output.linear = MathHelper.ConvertOrientationToVector(MathConstants.MATH_PI_2 / 3f).normalized; character.KinematicData.velocity = character.KinematicData.velocity.normalized * 30f; return output; } if (angleDiff > MathConstants.MATH_PI_4 && charSpeed >= 2500) // 2500 = 50^2 { output.linear = MathHelper.ConvertOrientationToVector(MathConstants.MATH_PI_4).normalized; character.KinematicData.velocity = character.KinematicData.velocity.normalized * 25f; return output; } if (angleDiffAbs >= MathConstants.MATH_PI_2 / 3f && charSpeed <= 100) // 100 = 10^2 { // aqui altera apenas a direcção em que em que o carro vira if (angleDiff < 0) { output.linear = MathHelper.ConvertOrientationToVector(character.KinematicData.orientation - MathConstants.MATH_PI_2 / 48f); character.KinematicData.velocity *= 2f; } else if (angleDiff >= 0) { output.linear = MathHelper.ConvertOrientationToVector(character.KinematicData.orientation + MathConstants.MATH_PI_2 / 48f); character.KinematicData.velocity *= 2f; } return output; } } return output; }
private static void CapCharacterVelocity(DynamicCharacter character) { var charSpeed = character.KinematicData.velocity.sqrMagnitude; if (charSpeed >= 900f) // 900 = 30^2 character.KinematicData.velocity *= 0.95f; else if (charSpeed >= 400f) // 400 = 20^2 character.KinematicData.velocity *= 0.97f; else if (charSpeed >= 100f) // 100 = 10^2 character.KinematicData.velocity *= 0.99f; }
public PedestrianAvoidanceConstraint(SteeringPipeline pipeline, DynamicCharacter character, List<Pedestrian> pedestrians) { this.Pedestrians = pedestrians; this.Character = character; }
public PathValidityCheckConstraint(DynamicCharacter character) { this.Character = character; }
// Use this for initialization void Awake() { this.draw = false; this.navMesh = NavigationManager.Instance.NavMeshGraphs [0]; this.character = new DynamicCharacter(this.characterAvatar); this.character.Drag = 0.5f; StringPullingPathSmoothing.MinWidth = 0.1f; this.aStarPathFinding = new NodeArrayAStarPathFinding(this.navMesh, new EuclideanHeuristic()); //this.aStarPathFinding = new AStarPathfinding(this.navMesh, new SimpleUnorderedNodeList(), new SimpleUnorderedNodeList(), new EuclideanDistanceHeuristic()); this.aStarPathFinding.NodesPerSearch = 100; }
private void InitializeSecondaryCharacter(DynamicCharacter character, GameObject[] obstacles) { var priority = new PriorityMovement { Character = character.KinematicData }; foreach (var obstacle in obstacles) { //TODO: add your AvoidObstacle movement here var avoidObstacleMovement = new DynamicAvoidObstacle(obstacle) { MaxAcceleration = MAX_ACCELERATION, avoidDistance = AVOID_MARGIN, lookAhead = MAX_LOOK_AHEAD, Character = this.RedCharacter.KinematicData, whiskersLookAhead = WHISKER_LOOK_AHEAD, MovementDebugColor = Color.magenta }; var AvoidObjects = new BlendedMovement(); AvoidObjects.Movements.Add(new MovementWithWeight(avoidObstacleMovement, 1.0f)); priority.Movements.Add(AvoidObjects); } var FlockMovement = new BlendedMovement(); var boidseparation = new DynamicSeparation(Characters) { Character = this.RedCharacter.KinematicData, MaxAcceleration = MAX_ACCELERATION, SeparationFactor = SEPARATION_FACTOR, Radius = RADIUS, MovementDebugColor = Color.green }; FlockMovement.Movements.Add(new MovementWithWeight(boidseparation, 5.0f)); var boidcohesion = new DynamicCohesion(Characters) { Character = this.RedCharacter.KinematicData, MaxAcceleration = MAX_ACCELERATION, FanAngle = FAN_ANGLE, Radius = RADIUS, MovementDebugColor = Color.red }; FlockMovement.Movements.Add(new MovementWithWeight(boidcohesion, 10.0f)); var boidvelocity = new DynamicFlockVelocityMatching(Characters) { Character = this.RedCharacter.KinematicData, MaxAcceleration = MAX_ACCELERATION, FanAngle = FAN_ANGLE, Radius = RADIUS, MovementDebugColor = Color.black }; FlockMovement.Movements.Add(new MovementWithWeight(boidvelocity, 3.0f)); var mouse = new DynamicMouseSeek { Character = this.RedCharacter.KinematicData, MaxAcceleration = MAX_ACCELERATION, MovementDebugColor = Color.blue, }; FlockMovement.Movements.Add(new MovementWithWeight(mouse, 8.0f)); priority.Movements.Add(FlockMovement); character.Movement = priority; }
// Use this for initialization void Awake() { this.draw = false; this.navMesh = NavigationManager.Instance.NavMeshGraphs[0]; this.character = new DynamicCharacter(this.characterAvatar); this.character.Drag = 0.3f; StringPullingPathSmoothing.MinWidth = 0.1f; this.aStarPathFindingEuclidean = new NodeArrayAStarPathFinding(this.navMesh, new EuclideanDistanceHeuristic()); this.aStarPathFindingGBEuclidean = new GoalBoundingNodeArrayAStarPathFinding(this.navMesh, new EuclideanDistanceHeuristic()); this.aStarPathFindingZero = new NodeArrayAStarPathFinding(this.navMesh, new ZeroHeuristic()); this.aStarPathFindingGBZero = new GoalBoundingNodeArrayAStarPathFinding(this.navMesh, new ZeroHeuristic()); this.aStarPathFindingEuclidean.NodesPerSearch = 100; this.aStarPathFindingZero.NodesPerSearch = 100; this.aStarPathFindingGBEuclidean.NodesPerSearch = 100; this.aStarPathFindingGBEuclidean.NodesPerSearch = 100; //default this.aStarPathFinding = this.aStarPathFindingGBEuclidean; currentAStar = "A* GoalBounding Euclidean Distance"; }
private List<DynamicCharacter> CloneSecondaryCharacters(GameObject objectToClone, int numberOfCharacters, GameObject[] obstacles) { var characters = new List<DynamicCharacter>(); for (int i = 0; i < numberOfCharacters; i++) { var clone = GameObject.Instantiate(objectToClone); clone.transform.position = this.GenerateRandomClearPosition(obstacles); var character = new DynamicCharacter(clone) { MaxSpeed = MAX_SPEED, Drag = DRAG }; characters.Add(character); } return characters; }
public StaticObstacleConstraint(DynamicCharacter character) { Character = character; }
public SteeringPipeline InitializeSteeringPipeline(DynamicCharacter orig) { //Pipeline SteeringPipeline pipe = new SteeringPipeline(orig.KinematicData) { MaxAcceleration = 15.0f }; //Targeter this.Targeter = new FixedTargeter(); pipe.Targeters.Add(this.Targeter); //Decomposer pathfindingDecomposer = new PathfindingDecomposer() { Graph = this.navMesh, Heuristic = new EuclideanDistanceHeuristic() }; pipe.Decomposers.Add(pathfindingDecomposer); //Actuator - Default: Car behaviour Actuator actuator = new CarActuator() { MaxAcceleration = 15.0f, Character = orig.KinematicData }; pipe.Actuator = actuator; /* if (orig.GameObject.tag.Equals("Enemies")) { actuator = new TrollActuator() { MaxAcceleration = 10.0f, Character = orig.KinematicData }; } pipe.Actuator = actuator; */ return pipe; }