public override void Orient(PlatformObject parent, Vector3 position, Quaternion rotation) { base.Orient(parent, position, rotation); platformParent = parent; platformParent.OnPlatformDeactivation += CollidableDeactivation; }
public void OnSceneGUI() { PlatformObject platformObject = (PlatformObject)target; if (!Application.isPlaying) { Quaternion cameraRotation = SceneView.currentDrawingSceneView.camera.transform.rotation; Handles.color = Color.white; Vector3 platformPosition = platformObject.transform.position; if (platformObject.controlPoints != null) { for (int i = 0; i < platformObject.controlPoints.Count; ++i) { Handles.DotCap(0, platformPosition + platformObject.controlPoints[i], cameraRotation, 0.1f); Vector3 prevPosition = platformPosition + platformObject.controlPoints[i]; Vector3 position = Handles.PositionHandle(platformPosition + platformObject.controlPoints[i], Quaternion.identity); if (prevPosition != position) { platformObject.controlPoints[i] = platformObject.transform.InverseTransformPoint(position); ComputeBezierCurve(false); } } } } ComputeBezierCurve(true); }
public override void Orient(PlatformObject parent, Vector3 position, Quaternion rotation) { base.Orient(parent, position, rotation); platformParent = parent; platformParent.OnPlatformDeactivation += CollidableDeactivation; }
public override void OnInspectorGUI() { base.OnInspectorGUI(); GUILayout.Space(10); CollidableAppearanceRules collidableAppearanceRules = (CollidableAppearanceRules)target; List<PlatformPlacementRule> platformPlacementRules = collidableAppearanceRules.avoidPlatforms; if (PlatformPlacementRuleInspector.showPlatforms(ref platformPlacementRules, false)) { collidableAppearanceRules.avoidPlatforms = platformPlacementRules; EditorUtility.SetDirty(target); } if (addNewAvoidPlatform) { GUILayout.BeginHorizontal(); GUILayout.Label("Target Platform"); targetPlatform = EditorGUILayout.ObjectField(targetPlatform, typeof(PlatformObject), false) as PlatformObject; GUILayout.EndHorizontal(); if (addError.Length > 0) { GUI.contentColor = Color.red; GUILayout.Label(addError); GUI.contentColor = Color.white; } GUILayout.BeginHorizontal(); if (GUILayout.Button("Add")) { int error; if ((error = PlatformPlacementRuleInspector.AddPlatform(ref platformPlacementRules, targetPlatform, false)) == 0) { addNewAvoidPlatform = false; collidableAppearanceRules.avoidPlatforms = platformPlacementRules; EditorUtility.SetDirty(target); } else { switch (error) { case 1: addError = "Error: Target Platform is not set"; break; case 2: addError = "Error: Target Platform has already been added"; break; default: addError = "Unknown Error"; break; } } } if (GUILayout.Button("Cancel")) { addNewAvoidPlatform = false; } GUILayout.EndHorizontal(); } if (!addNewAvoidPlatform && GUILayout.Button("Add Avoid Platform")) { addError = ""; addNewAvoidPlatform = true; } }
public override void Orient(PlatformObject parent, Vector3 position, Quaternion rotation) { base.Orient(parent, position, rotation); collideWithPlayer = true; moving = (startMoveSquaredDistance == 0); lastSquareMagnitude = Mathf.Infinity; yAngle = thisTransform.eulerAngles.y; }
public override void Orient(PlatformObject parent, Vector3 position, Quaternion rotation) { base.Orient(parent, position, rotation); collideWithPlayer = true; moving = (startMoveSquaredDistance == 0); lastSquareMagnitude = Mathf.Infinity; yAngle = thisTransform.eulerAngles.y; }
// orient for collidables which have a platform as a parent public virtual void Orient(PlatformObject parent, Vector3 position, Quaternion rotation) { thisTransform.parent = parent.GetTransform(); Vector3 pos = Vector3.zero; float yAngle = rotation.eulerAngles.y; pos.Set(startPosition.x * Mathf.Cos(yAngle * Mathf.Deg2Rad) + startPosition.z * Mathf.Sin(yAngle * Mathf.Deg2Rad), startPosition.y, -startPosition.x * Mathf.Sin(yAngle * Mathf.Deg2Rad) + startPosition.z * Mathf.Cos(yAngle * Mathf.Deg2Rad)); pos += position; thisTransform.localPosition = parent.GetTransform().InverseTransformPoint(pos); thisTransform.rotation = startRotation; thisTransform.Rotate(0, rotation.eulerAngles.y, 0, Space.World); }
public void ResetValues(bool fromRevive) { slideData.duration = 0; stumbleData.duration = 0; jumpSpeed = 0; isJumping = false; isJumpPending = false; isSliding = false; isStumbling = false; onGround = true; prevHitTransform = null; canUpdatePosition = true; playerAnimation.ResetValues(); if (projectileManager) projectileManager.ResetValues(); pauseCollisionParticlePlaying = false; turnTime = -simultaneousTurnPreventionTime; jumpLandTime = Time.time; platformObject = null; curveTime = -1; curveMoveDistance = 0; curveDistanceMapIndex = 0; followCurve = false; if (!fromRevive) { currentSlotPosition = SlotPosition.Center; targetHorizontalPosition = (int)currentSlotPosition * infiniteObjectGenerator.slotDistance; totalMoveDistance = 0; turnOffset = prevTurnOffset = Vector3.zero; curveOffset = Vector3.zero; forwardSpeeds.ResetValues(); thisTransform.position = startPosition; thisTransform.rotation = startRotation; targetRotation = startRotation; UpdateTargetPosition(targetRotation.eulerAngles.y); reviveTime = -1; } else { reviveTime = Time.time; } }
public override void Init() { base.Init(); platformObject = GetComponent<PlatformObject>(); }
// returns true if there is still space on the platform for a collidable object to spawn private void SpawnCollidable(ObjectType objectType, Vector3 position, Vector3 direction, ObjectLocation location, PlatformObject platform, int platformLocalIndex, bool activateImmediately) { int collidablePositions = platform.collidablePositions; // can't do anything if the platform doesn't accept any collidable object spawns if (collidablePositions == 0) return; Vector3 offset = platformSizes[platformLocalIndex] * 0.1f; float zDelta = platformSizes[platformLocalIndex].z * .8f / (1 + collidablePositions); for (int i = 0; i < collidablePositions; ++i) { if (platform.CanSpawnCollidable(i)) { spawnData.slotPositions = platform.GetSlotsAvailable(); int localIndex = infiniteObjectManager.GetNextObjectIndex(objectType, spawnData); if (localIndex != -1) { CollidableObject collidable = infiniteObjectManager.ObjectFromPool(localIndex, objectType) as CollidableObject; Quaternion lookRotation = Quaternion.LookRotation(direction); Vector3 spawnSlot = collidable.GetSpawnSlot(platform.GetTransform().right * slotDistance, spawnData.slotPositions); collidable.Orient(platform, position + (offset.z + ((i + 1) * zDelta)) * direction + spawnSlot, lookRotation); if (activateImmediately) collidable.Activate(); int objectIndex = infiniteObjectManager.LocalIndexToObjectIndex(localIndex, objectType); infiniteObjectHistory.ObjectSpawned(objectIndex, (offset.z + ((i + 1) * zDelta)), location, lookRotation.eulerAngles.y, objectType); platform.CollidableSpawned(i); // don't allow any more of the same collidable type if we are forcing a different collidable if (platform.forceDifferentCollidableTypes) break; } } } spawnData.slotPositions = 0; }
// a platform has been spawned, now spawn the scene objects and setup for a turn if needed private void PlatformSpawned(PlatformObject platform, ObjectLocation location, Vector3 direction, bool activateImmediately) { bool isTurn = platform.leftTurn || platform.rightTurn; if (isTurn || spawnFullLength) { // set largestScene to 0 to prevent the scene spawner from waiting for space for the largest scene object spawnData.largestScene = 0; spawnData.useWidthBuffer = false; } // spawn all of the scene objects until we have spawned enough scene objects SetupSection(location, true); int localIndex; SceneObject scene = null; while ((localIndex = infiniteObjectManager.GetNextObjectIndex(ObjectType.Scene, spawnData)) != -1) { Vector3 position = Vector3.zero; SceneObject prevScene = infiniteObjectHistory.GetTopInfiniteObject(location, true) as SceneObject; bool useZSize = true; int prevSceneIndex; // may be null if coming from a turn if (prevScene == null) { if (location != ObjectLocation.Center) { prevSceneIndex = sceneTurnIndex[(int)ObjectLocation.Center]; prevScene = turnScene[(int)ObjectLocation.Center]; } else { prevScene = infiniteObjectHistory.GetTopInfiniteObject(location, true) as SceneObject; prevSceneIndex = infiniteObjectHistory.GetLastLocalIndex(location, ObjectType.Scene); } useZSize = false; } else { prevSceneIndex = infiniteObjectHistory.GetLastLocalIndex(location, ObjectType.Scene); } if (prevScene) { position = prevScene.GetTransform().position - sceneStartPosition[prevSceneIndex] + (useZSize ? sceneSizes[prevSceneIndex].z : sceneSizes[prevSceneIndex].x) / 2 * direction + sceneSizes[prevSceneIndex].y * Vector3.up; } scene = SpawnSceneObject(localIndex, location, position, direction, activateImmediately); // the section may change because of the newly spawned scene object SetupSection(location, true); } if (isTurn) { spawnData.largestScene = largestSceneLength; spawnData.useWidthBuffer = true; turnPlatform[(int)location] = platform; turnIndex[(int)location] = infiniteObjectHistory.GetLastLocalIndex(location, ObjectType.Platform); turnScene[(int)location] = scene; sceneTurnIndex[(int)location] = infiniteObjectHistory.GetLastLocalIndex(location, ObjectType.Scene); if (location == ObjectLocation.Center) { infiniteObjectHistory.ResetTurnCount(); } } else if (platform.sectionTransition) { infiniteObjectHistory.DidSpawnSectionTranition(location, false); } }
// orient for collidables which have a platform as a parent public virtual void Orient(PlatformObject parent, Vector3 position, Quaternion rotation) { thisTransform.parent = parent.GetTransform(); Vector3 pos = Vector3.zero; float yAngle = rotation.eulerAngles.y; pos.Set(startPosition.x * Mathf.Cos(yAngle * Mathf.Deg2Rad) + startPosition.z * Mathf.Sin(yAngle * Mathf.Deg2Rad), startPosition.y, -startPosition.x * Mathf.Sin(yAngle * Mathf.Deg2Rad) + startPosition.z * Mathf.Cos(yAngle * Mathf.Deg2Rad)); pos += position; thisTransform.localPosition = parent.GetTransform().InverseTransformPoint(pos); thisTransform.rotation = startRotation; thisTransform.Rotate(0, rotation.eulerAngles.y, 0, Space.World); }
public void Start() { platform = transform.parent.GetComponent<PlatformObject>(); }
// There character doesn't move, all of the objects around it do. Make sure the character is in the correct position public void Update() { Vector3 moveDirection = Vector3.zero; float hitDistance = 0; RaycastHit hit; // cast a ray to see if we are over any platforms if (Physics.Raycast(thisTransform.position + capsuleCollider.center, -thisTransform.up, out hit, Mathf.Infinity, platformLayer)) { hitDistance = hit.distance; PlatformObject platform = null; if (!hit.transform.Equals(prevHitTransform)) { prevHitTransform = hit.transform; // update the platform object if (((platform = hit.transform.GetComponent<PlatformObject>()) != null) || ((platform = hit.transform.parent.GetComponent<PlatformObject>()) != null)) { if (platform != platformObject) { platformObject = platform; CheckForCurvedPlatform(); } } } // we are over a platform, determine if we are on the ground of that platform if (hit.distance <= capsuleCollider.height / 2 + 0.0001f + pivotOffset.y) { onGround = true; // we are on the ground. Get the platform object and check to see if we are on a curve // if we are sliding and the platform has a slope then stop sliding if (isSliding) { if (platformObject != null && platformObject.slope != PlatformSlope.None) { StopCoroutine("DoSlide"); StopSlide(true); } } // if we are jumping we either want to start jumping or land if (isJumping) { if (isJumpPending) { moveDirection.y += jumpSpeed; cameraController.AdjustVerticalOffset(jumpSpeed * Time.deltaTime); jumpSpeed += gravity * Time.deltaTime; onGround = false; } else { isJumping = false; jumpLandTime = Time.time; if (gameManager.IsGameActive()) playerAnimation.Run(); groundCollisionParticleSystem.Play(); } } else { // we are not jumping so our position should be the same as the hit point Vector3 position = thisTransform.position; position.y = hit.point.y; thisTransform.position = position + pivotOffset; } skipFrame = true; // a hit distance of -1 means that the platform is within distance hitDistance = -1; } // if we didn't hit a platform we may hit a floor } else if (Physics.Raycast(thisTransform.position + capsuleCollider.center, -thisTransform.up, out hit, Mathf.Infinity, floorLayer)) { hitDistance = hit.distance; } if (hitDistance != -1) { // a platform is beneith us but it is far away. If we are jumping apply the jump speed and gravity if (isJumping) { moveDirection.y += jumpSpeed; cameraController.AdjustVerticalOffset(jumpSpeed * Time.deltaTime); jumpSpeed += gravity * Time.deltaTime; // the jump is no longer pending if we are in the air if (isJumpPending) { isJumpPending = false; } } else if (!skipFrame) { // apply gravity if we are not jumping moveDirection.y = gravity * (powerUpManager.IsPowerUpActive(PowerUpTypes.SpeedIncrease) ? 2 : 1); // the speed power up needs a little extra push } if (!skipFrame && hitDistance == 0) { platformObject = null; } if (skipFrame) { skipFrame = false; } else if (hitDistance != 0 && thisTransform.position.y + (moveDirection.y * Time.deltaTime) < hit.point.y) { // this transition should be instant so ignore Time.deltaTime moveDirection.y = (hit.point.y - thisTransform.position.y) / Time.deltaTime; } onGround = false; } float xStrafe = (targetPosition.x - thisTransform.position.x) * Mathf.Abs(Mathf.Cos(targetRotation.eulerAngles.y * Mathf.Deg2Rad)) / Time.deltaTime; float zStrafe = (targetPosition.z - thisTransform.position.z) * Mathf.Abs(Mathf.Sin(targetRotation.eulerAngles.y * Mathf.Deg2Rad)) / Time.deltaTime; moveDirection.x += Mathf.Clamp(xStrafe, -horizontalSpeed, horizontalSpeed); moveDirection.z += Mathf.Clamp(zStrafe, -horizontalSpeed, horizontalSpeed); thisTransform.position += moveDirection * Time.deltaTime; // Make sure we don't run into a wall if (Physics.Raycast(thisTransform.position + Vector3.up, thisTransform.forward, capsuleCollider.radius, wallLayer)) { gameManager.GameOver(GameOverType.Wall, true); } if (!gameManager.IsGameActive()) { enabled = InAir(); // keep the character active for as long as they are in the air so gravity can keep pushing them down. } }
// Turn left or right public bool Turn(bool rightTurn, bool fromInputManager) { // prevent two turns from occurring really close to each other (for example, to prevent a 180 degree turn) if (Time.time - turnTime < simultaneousTurnPreventionTime) { return false; } RaycastHit hit; // ensure we are over the correct platform if (Physics.Raycast(thisTransform.position + capsuleCollider.center, -thisTransform.up, out hit, Mathf.Infinity, platformLayer)) { PlatformObject platform = null; // update the platform object if (((platform = hit.transform.GetComponent<PlatformObject>()) != null) || ((platform = hit.transform.parent.GetComponent<PlatformObject>()) != null)) { if (platform != platformObject) { platformObject = platform; CheckForCurvedPlatform(); } } } bool isAboveTurn = AbovePlatform(true); // if we are restricting a turn, don't turn unless we are above a turn platform if (restrictTurns && (!isAboveTurn || restrictTurnsToTurnTrigger)) { if (fromInputManager) { turnRequestTime = Time.time; turnRightRequest = rightTurn; return false; } if (!powerUpManager.IsPowerUpActive(PowerUpTypes.Invincibility) && !powerUpManager.IsPowerUpActive(PowerUpTypes.SpeedIncrease) && !autoTurn && !WithinReviveGracePeriod()) { // turn in the direction that the player swiped rightTurn = turnRightRequest; // don't turn if restrict turns is on and the player hasn't swipped within the grace period time or if the player isn't above a turn platform if (!gameManager.godMode && (Time.time - turnRequestTime > turnGracePeriod || !isAboveTurn)) { return false; } } } else if (!fromInputManager && !autoTurn && !gameManager.godMode && (!restrictTurns || Time.time - turnRequestTime > turnGracePeriod) && !powerUpManager.IsPowerUpActive(PowerUpTypes.Invincibility) && !powerUpManager.IsPowerUpActive(PowerUpTypes.SpeedIncrease) && !WithinReviveGracePeriod()) { return false; } turnTime = Time.time; Vector3 direction = platformObject.GetTransform().right * (rightTurn ? 1 : -1); prevTurnOffset = turnOffset; canUpdatePosition = infiniteObjectGenerator.UpdateSpawnDirection(direction, platformObject.curveLength == 0, rightTurn, isAboveTurn, out turnOffset); if (canUpdatePosition && platformObject.curveLength > 0) { followCurve = true; } else { targetRotation = Quaternion.LookRotation(direction); curveOffset.x = (thisTransform.position.x - (startPosition.x + turnOffset.x)) * Mathf.Abs(Mathf.Sin(targetRotation.eulerAngles.y * Mathf.Deg2Rad)); curveOffset.z = (thisTransform.position.z - (startPosition.z + turnOffset.z)) * Mathf.Abs(Mathf.Cos(targetRotation.eulerAngles.y * Mathf.Deg2Rad)); if (isAboveTurn) { UpdateTargetPosition(targetRotation.eulerAngles.y); } } return true; }
private void ComputeBezierCurve(bool draw /*if false, will compute length*/) { PlatformObject platformObject = (PlatformObject)target; if (platformObject.controlPoints == null || platformObject.controlPoints.Count < 3) { platformObject.curveLength = 0; EditorUtility.SetDirty(target); return; } if (!draw) { platformObject.curveIndexDistanceMap = new List <float>(); } Vector3 p0, p1, p2; Vector3 q0, q1; float t; float length = 0; Handles.color = Color.white; Vector3 platformPosition = platformObject.transform.position; for (int i = 0; i < platformObject.controlPoints.Count - 2; ++i) { if (i == 0) { p0 = platformObject.controlPoints[i]; } else { p0 = (platformObject.controlPoints[i] + platformObject.controlPoints[i + 1]) / 2; } p1 = platformObject.controlPoints[i + 1]; if (i + 2 == platformObject.controlPoints.Count - 1) { p2 = platformObject.controlPoints[i + 2]; } else { p2 = (platformObject.controlPoints[i + 1] + platformObject.controlPoints[i + 2]) / 2; } t = 0; q0 = InfiniteRunnerStarterPackUtility.CalculateBezierPoint(p0, p1, p2, t); for (int j = 1; j <= StepCount; j++) { t = j / (float)StepCount; q1 = InfiniteRunnerStarterPackUtility.CalculateBezierPoint(p0, p1, p2, t); if (draw) { Handles.DrawLine(platformPosition + q0, platformPosition + q1); } else { length += Vector3.Distance(q0, q1); } q0 = q1; } if (!draw) { platformObject.curveIndexDistanceMap.Add(length); } } if (!draw) { platformObject.curveLength = length; EditorUtility.SetDirty(target); } }
public override void OnInspectorGUI() { base.OnInspectorGUI(); PlatformObject platformObject = (PlatformObject)target; bool sectionTransition = EditorGUILayout.Toggle("Is Section Transition", platformObject.sectionTransition); if (sectionTransition != platformObject.sectionTransition) { platformObject.sectionTransition = sectionTransition; EditorUtility.SetDirty(target); } if (sectionTransition) { List <int> fromSection = platformObject.fromSection; List <int> toSection = platformObject.toSection; if (SectionSelectionInspector.ShowSectionTransitions(ref fromSection, ref toSection)) { platformObject.fromSection = fromSection; platformObject.toSection = toSection; EditorUtility.SetDirty(target); } } List <Vector3> controlPoints = platformObject.controlPoints; if (controlPoints != null && controlPoints.Count > 0) { bool updated = false; GUILayout.Label("Control Points:"); for (int i = 0; i < controlPoints.Count; ++i) { GUILayout.BeginHorizontal(GUILayout.Width(100)); GUILayout.Label(string.Format("{0} - {1}", i + 1, controlPoints[i])); if (GUILayout.Button("X", GUILayout.Width(30))) { controlPoints.RemoveAt(i); updated = true; break; } GUILayout.EndHorizontal(); } if (updated) { platformObject.controlPoints = controlPoints; ComputeBezierCurve(false); EditorUtility.SetDirty(target); } } if (GUILayout.Button("Add Control Point")) { if (controlPoints == null) { controlPoints = new List <Vector3>(); } controlPoints.Add(Vector3.up); platformObject.controlPoints = controlPoints; ComputeBezierCurve(false); EditorUtility.SetDirty(target); } }