/** * Each frame, the current state must provide five things: * * Vector3 targetPosition = the position in the world that the helicopter should fly to * float currSpeed = the speed that the helicopter should move towards that position * Quaternion desiredSpotlightRotation = the Quaternion representation of the rotation that the spotlight should rotate towards * float spotlightMoveSpeed = the speed that the spotlight should rotate towards that rotation * bool newDirection = For this frame, newDirection = 1 if movingRight should be changed, 0 if it should stay the same. */ private void updateState() { state = state.updateState(Time.deltaTime); movingRight = (state.newDirection()) ? !movingRight : movingRight; transform.position = Vector3.MoveTowards(transform.position, state.getTargetPosition(), state.getCurrSpeed() * Time.deltaTime); spotlight.transform.rotation = Quaternion.RotateTowards(spotlight.transform.rotation, state.getTargetSpotlightRotation(), state.getSpotlightRotationSpeed() * Time.deltaTime); }
/** * The default constructor for FlipState. * This makes the assumption that we can finish this FlipState with * the position of the helicopter after the flip as the root, and then * begin the movement pattern from there (starting sine wave at t=0). * Because of this, this shouldn't be called by IdleState, as it can * result in the helicopter repeatedly changing it's anchor height after * every flip, over time making the helicopter descend or ascend significantly */ public FlipState(HeliScript helicopter, float deltaTime, HelicopterState toReturnTo) { //Initializing default, independent vals for behavioral variables this.helicopter = helicopter; timeIntoFlip = 0f; haveFlipped = false; flippedThisFrame = false; rootPosition = toReturnTo.getTargetPosition(); rootPosition.y -= helicopter.yOffsetMovement.indexedValue(); //since we adjust for bob, remove from root position this.toReturnTo = toReturnTo; justSawPlayer = false; initialSpeed = (helicopter.getMovingRight()) ? helicopter.speed : -helicopter.speed; //initalize debug vars //currSpeedDebug = new List<float>(); //targetPositionDebug = new List<float> (); //Shortcuts for accessing frequent variables without reaching back into helicopter each time lengthOfFlipInSeconds = helicopter.flipTime; halfwayPoint = lengthOfFlipInSeconds / 2; spotlightRotationBeforeFlip = helicopter.getSpotlight().transform.rotation; //Only need to calculate new spotlight rotation once, as it is simply the negated spotlight's rotation along the z axis targetSpotlightRotation = calculateNewSpotlightRotation(); //Similarly, only need to calculate spotlight rotation speed once, as it's just the value that is scaled by time //to allow the spotlight to rotate smoothly and end exactly on the rotation point at helicopter.flipTime seconds spotlightRotationSpeed = calculateSpotlightRotationSpeed(targetSpotlightRotation.eulerAngles.z); //Must call this once during the constructor so that we have values initiated for the first frame of it's instantiation updateState(deltaTime); }
//Constructor run when creating IdleState public ReturnToStateState(HeliScript helicopter, float deltaTime, HelicopterState toReturnTo) { this.helicopter = helicopter; nextState = toReturnTo; targetPosition = nextState.getTargetPosition(); spotlightRotationSpeed = nextState.getSpotlightRotationSpeed(); targetSpotlightRotation = nextState.getTargetSpotlightRotation(); currSpeed = helicopter.speed; if ((helicopter.getMovingRight() && toReturnTo.getTargetPosition().x < helicopter.transform.position.x) || (!helicopter.getMovingRight() && toReturnTo.getTargetPosition().x > helicopter.transform.position.x)) { //We gotta turn around first toDoFirst = new FlipState(helicopter, deltaTime, this); } updateState(deltaTime); }