using SHADE; using System; using System.Collections.Generic; using SHADE_Scripting.Audio; using static Item; public class PlayerController : Script { public enum RaccoonStates { IDLE, WALKING, RUNNING, JUMP, FALLING, LANDED, CAUGHT, TOTAL } public RigidBody rb { get; set; } public Transform tranform { get; set; } public Camera cam { get; set; } public CameraArm camArm { get; set; } private PickAndThrow pat; public StateMachine stateMachine { get; set; } public ParticleEmitter smoke { get; set; } public bool holdItem { get; set; } public bool isAiming { get; set; } [Tooltip("The game object for where the player will respawn to")] public GameObject respawnPoint; private float delayTimer = 0.0f; [Tooltip("The current state fo the raccoon")] public RaccoonStates currentState; //Movement variables============================================================ [Tooltip("Max vel for walking")] public float walkMaxMoveVel = 3.0f; [Tooltip("how much force is apply for walking")] public float moveForce = 50.0f; [Tooltip("increase the moveForce and maxMoveVel by its amt")] public float sprintMultiplier = 1.5f; private float oldForce; private float maxOldVel; private bool sprintIncreaseOnce = false; public Vector2 axisMove { get; set; } public bool isMoveKeyPress { get; set; } [Tooltip("How fast player will turn")] public float rotationFactorPerFrame = 5.0f; //Jumping vars================================================================== [Tooltip("max height of the jump")] public float maxJumpHeight = 1.0f; [Tooltip("max amount of time it will take for the jump")] public float maxJumpTime = 0.5f; [Tooltip("increase gravity when falling")] public float fallMultipler = 3.0f; private float initialJumpVel; private bool isGrounded = true; private float gravity = -9.8f; private float groundGravity = -0.5f; public bool landedOnJumpPad { get; set; } [Tooltip("multiply height on Jump Pad ")] public float jumpPadMultiplayer = 2.0f; private bool jumpPadDrop = false; private float dropTimer = 0.0f; public float dropDuration = 0.5f; public float jumpPadFallMultipler = 0.75f; public float jumpPadMaxMoveVel = 1.0f; private float currMoveVel = 0.0f; //ItemMultipler================================================================== [Tooltip("How light item will affect player jump")] public float lightMultiper = 0.75f; [Tooltip("How medium item will affect player jump")] public float mediumMultiper = 0.5f; [Tooltip("How heavy item will affect player jump")] public float heavyMultiper = 0.25f; //silhouette===================================================================== public GameObject silhouettePlayer; private Renderable silhouettePlayerRend; public GameObject silhouetteBag; private Renderable silhouetteBagRend; public bool playLandedAnimation { get; set; } protected override void awake() { //default setup isMoveKeyPress = false; holdItem = false; isAiming = false; landedOnJumpPad = false; //Jump setup float timeToApex = maxJumpTime / 2; gravity = (-2 * maxJumpHeight) / MathF.Pow(timeToApex, 2); initialJumpVel = (2 * maxJumpHeight) / timeToApex; //rigidbody check rb = GetComponent(); if (!rb) Debug.LogError("RigidBody is MISSING!"); //Transform check tranform = GetComponent(); if(!tranform) Debug.LogError("tranform is MISSING!"); stateMachine = AddScript(); Dictionary dictionary = new Dictionary(); dictionary.Add(typeof(PlayerIdleState), new PlayerIdleState(stateMachine)); dictionary.Add(typeof(PlayerWalkState), new PlayerWalkState(stateMachine)); dictionary.Add(typeof(PlayerRunState), new PlayerRunState(stateMachine)); dictionary.Add(typeof(PlayerJumpState), new PlayerJumpState(stateMachine)); dictionary.Add(typeof(PlayerFallState), new PlayerFallState(stateMachine)); dictionary.Add(typeof(PlayerLandState), new PlayerLandState(stateMachine)); dictionary.Add(typeof(PlayerCaughtState), new PlayerCaughtState(stateMachine)); stateMachine.InitStateMachine(dictionary); if (!silhouettePlayer) Debug.LogError("silhouettePlayer EMPTY"); else { silhouettePlayerRend = silhouettePlayer.GetComponent(); silhouettePlayerRend.Material.SetProperty("data.offset", 0.1f); } if (!silhouetteBag) Debug.LogError("silhouetteBag EMPTY"); else { silhouetteBagRend = silhouetteBag.GetComponent(); silhouetteBagRend.Material.SetProperty("data.offset", 0.1f); } AudioHandler.audioClipHandlers["footsteps"] = Audio.CreateAudioClip("event:/Raccoon/raccoon_footsteps"); playLandedAnimation = false; smoke = GetComponentInChildren(); if (!smoke) Debug.LogError("ParticleEmitter MISSING"); } protected override void start() { currentState = RaccoonStates.IDLE; stateMachine.SetState(typeof(PlayerIdleState)); } protected override void lateUpdate() { } protected override void update() { if (GameManager.Instance.GamePause || !GameManager.Instance.stealFoodPopUpDone) { return; } if (silhouettePlayerRend && silhouetteBagRend) { Vector3 dis = Camera.GetMainCamera().Position - GameObject.GetComponent().LocalPosition; float disSqr = dis.GetSqrMagnitude(); float ratio = System.Math.Clamp(1 - (disSqr / (1 + disSqr)), 0, 1.0f); float temp = (1 - ratio) * 0.00075f; if (temp <= 0.0006f) temp = 0.1f; silhouettePlayerRend.Material.SetProperty("data.offset", temp); silhouetteBagRend.Material.SetProperty("data.offset", temp); } //PickAndThrow check if (!pat) { pat = GetScript(); if(!pat) Debug.LogError("PickAndThrow is NULL!"); } if (!cam) { cam = GetComponentInChildren(); if (pat) { cam.FOV = Settings.cameraFOV; } } if (!camArm) { camArm = GetComponentInChildren(); pat.prevTargetOffSet = camArm.TargetOffset; } if (jumpPadDrop && currentState == RaccoonStates.FALLING) { dropTimer += Time.DeltaTimeF; if (dropTimer > dropDuration) { jumpPadDrop = false; dropTimer = 0.0f; currMoveVel = walkMaxMoveVel; } } GotCaught(); Rotation(); MoveKey(); Sprint(); Jump(); //Debug.Log($"{currentState}"); //Debug.Log($" axisX: {axisMove.x} axisY:{axisMove.y}"); //Debug.Log($"X: {rb.LinearVelocity.x}" + $" Z: {rb.LinearVelocity.z}"); //Debug.Log(currentState.ToString() + " x:" + rb.LinearVelocity.x.ToString() + " y:" + rb.LinearVelocity.y.ToString() + " z:" + rb.LinearVelocity.z.ToString()); } protected override void fixedUpdate() { if (GameManager.Instance.GamePause || !GameManager.Instance.stealFoodPopUpDone) { return; } Move(); Gravity(); } private void MoveKey() { axisMove = Vector2.Zero; if (Input.GetKey(Input.KeyCode.W)) { Vector3 camerAixs = cam.GetForward(); camerAixs.y = 0; camerAixs.Normalise(); axisMove += new Vector2(camerAixs.x, camerAixs.z); } if (Input.GetKey(Input.KeyCode.S)) { Vector3 camerAixs = cam.GetForward(); camerAixs.y = 0; camerAixs.Normalise(); axisMove -= new Vector2(camerAixs.x, camerAixs.z); } if (Input.GetKey(Input.KeyCode.A)) { Vector3 camerAixs = cam.GetRight(); camerAixs.y = 0; camerAixs.Normalise(); axisMove -= new Vector2(camerAixs.x, camerAixs.z); } if (Input.GetKey(Input.KeyCode.D)) { Vector3 camerAixs = cam.GetRight(); camerAixs.y = 0; camerAixs.Normalise(); axisMove += new Vector2(camerAixs.x, camerAixs.z); } axisMove.Normalise(); isMoveKeyPress = axisMove.x != 0 || axisMove.y != 0; if (isMoveKeyPress && isGrounded && !Input.GetKey(Input.KeyCode.LeftShift)) { currentState = RaccoonStates.WALKING; if(stateMachine && !stateMachine.IsState(typeof(PlayerWalkState))) stateMachine.SetState(typeof(PlayerWalkState)); } if (!isMoveKeyPress && isGrounded) { currentState = RaccoonStates.IDLE; if(stateMachine && !stateMachine.IsState(typeof(PlayerIdleState))) stateMachine.SetState(typeof(PlayerIdleState)); } } private void Move() { if (rb != null && currentState != RaccoonStates.CAUGHT) { rb.LinearVelocity += new Vector3(axisMove.x * moveForce, 0.0f, axisMove.y * moveForce) * Time.DeltaTimeF; if (isMoveKeyPress && rb) { Vector3 velNor = rb.LinearVelocity; velNor.y = 0.0f; if (jumpPadDrop) currMoveVel = jumpPadMaxMoveVel; else currMoveVel = walkMaxMoveVel; if (velNor.GetMagnitude() > currMoveVel) { velNor.Normalise(); velNor *= currMoveVel; rb.LinearVelocity = new Vector3(velNor.x, rb.LinearVelocity.y, velNor.z); } } } } private void Sprint() { if (Input.GetKey(Input.KeyCode.LeftShift) && isMoveKeyPress && isGrounded) { currentState = RaccoonStates.RUNNING; if (stateMachine && !stateMachine.IsState(typeof(PlayerRunState))) stateMachine.SetState(typeof(PlayerRunState)); holdItem = false; if (!sprintIncreaseOnce) { sprintIncreaseOnce = true; oldForce = moveForce; moveForce *= sprintMultiplier; maxOldVel = walkMaxMoveVel; walkMaxMoveVel *= sprintMultiplier; } } if (Input.GetKeyUp(Input.KeyCode.LeftShift)) { if (isMoveKeyPress && isGrounded) { currentState = RaccoonStates.WALKING; if (stateMachine && !stateMachine.IsState(typeof(PlayerWalkState))) stateMachine.SetState(typeof(PlayerWalkState)); } else if(!isMoveKeyPress && isGrounded) { currentState = RaccoonStates.IDLE; if (stateMachine && !stateMachine.IsState(typeof(PlayerIdleState))) stateMachine.SetState(typeof(PlayerIdleState)); } sprintIncreaseOnce = false; moveForce = oldForce; walkMaxMoveVel = maxOldVel; } } private void Jump() { if (currentState == RaccoonStates.WALKING || currentState == RaccoonStates.RUNNING || currentState == RaccoonStates.IDLE) { if ( (Input.GetKeyDown(Input.KeyCode.Space) || landedOnJumpPad ) && isGrounded && rb != null) { isGrounded = false; currentState = RaccoonStates.JUMP; if (stateMachine && !stateMachine.IsState(typeof(PlayerJumpState))) stateMachine.SetState(typeof(PlayerJumpState)); Vector3 v = rb.LinearVelocity; v.y = initialJumpVel * 0.5f; if (holdItem && pat != null && pat.item.GetScript() != null) { Item item = pat.item.GetScript(); if (item != null && item.currCategory == ItemCategory.LIGHT) v.y *= lightMultiper; if (item != null && item.currCategory == ItemCategory.MEDIUM) v.y *= mediumMultiper; if (item != null && item.currCategory == ItemCategory.HEAVY) v.y *= heavyMultiper; } if (landedOnJumpPad) { v.y *= jumpPadMultiplayer; landedOnJumpPad = false; jumpPadDrop = true; } rb.LinearVelocity = v; } } if (!isGrounded && rb != null && (rb.LinearVelocity.y < 0.0f || Input.GetKeyUp(Input.KeyCode.Space))) { currentState = RaccoonStates.FALLING; if (stateMachine && !stateMachine.IsState(typeof(PlayerFallState))) stateMachine.SetState(typeof(PlayerFallState)); } } private void Rotation() { tranform.LocalEulerAngles = new Vector3(0.0f, tranform.LocalEulerAngles.y, 0.0f); if (isMoveKeyPress && tranform && !isAiming) { Quaternion currentRotation = tranform.LocalRotation; Quaternion targetRotation = Quaternion.Euler(0.0f, MathF.Atan2(axisMove.x,axisMove.y), 0.0f); tranform.LocalRotation = Quaternion.Slerp(currentRotation, targetRotation, rotationFactorPerFrame * (float)Time.FixedDeltaTime); } else if (camArm && tranform && isAiming) { Quaternion currentRotation = tranform.LocalRotation; Quaternion targetRotation = Quaternion.Euler(0.0f, SHADE.Math.DegreesToRadians(camArm.Yaw + 180.0f), 0.0f); tranform.LocalRotation = Quaternion.Slerp(currentRotation, targetRotation, rotationFactorPerFrame * (float)Time.FixedDeltaTime); } } private void Gravity() { if (rb != null) { //check player vel.y if its close to zero its on the ground if (SHADE.Math.CompareFloat(rb.LinearVelocity.y, 0.0f)) { isGrounded = true; if (currentState == RaccoonStates.FALLING) { currentState = RaccoonStates.LANDED; jumpPadDrop = false; dropTimer = 0.0f; currMoveVel = walkMaxMoveVel; playLandedAnimation = true; if (stateMachine && !stateMachine.IsState(typeof(PlayerLandState))) stateMachine.SetState(typeof(PlayerLandState)); } } else isGrounded = false; Vector3 v = rb.LinearVelocity; if (isGrounded) v.y = groundGravity; else if (currentState == RaccoonStates.FALLING) { float prevYVel = v.y; float newYVel = 0; if (jumpPadDrop) newYVel = v.y + (gravity * jumpPadFallMultipler * (float)Time.FixedDeltaTime); else newYVel = v.y + (gravity * fallMultipler * (float)Time.FixedDeltaTime); float nextYVel = (prevYVel + newYVel) * 0.5f; v.y = nextYVel; } else { float prevYVel = v.y; float newYVel = v.y + (gravity * (float)Time.FixedDeltaTime); float nextYVel = (prevYVel + newYVel) * 0.5f; v.y = nextYVel; } rb.LinearVelocity = v; } } private void GotCaught() { if (currentState == RaccoonStates.CAUGHT && tranform && respawnPoint) { currentState = RaccoonStates.IDLE; if (stateMachine && !stateMachine.IsState(typeof(PlayerIdleState))) stateMachine.SetState(typeof(PlayerIdleState)); tranform.LocalPosition = respawnPoint.GetComponent().LocalPosition; GameManager.Instance.RacoonCaught(); if (pat && pat.item) { if (holdItem) { holdItem = false; pat.item.GetScript().returnBack = true; } if (isAiming) { isAiming = false; cam.FOV = Settings.cameraFOV; camArm.TargetOffset = pat.prevTargetOffSet; camArm.ArmLength = pat.tpc.armLength; } } } } protected override void onCollisionEnter(CollisionInfo info) { } }