mvaganov

RBAgent.cs

May 14th, 2019
138
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5. using Cinemachine.Utility;// for ProjectOntoPlane
  6. using UnityEngine.Serialization;
  7. using Random = UnityEngine.Random;
  8.  
  9. // TODO create the RBAgentCamera (and eyes) with a ContextMenuItem, or automatically if the agent is marked as Player
  10. // TODO ContextMenuItem to create sphere collider
  11. // TODO fix min/max pitch
  12. // TODO camera control variables to the RBAgentCamera
  13. // using Lines drawing code at: https://raw.githubusercontent.com/mvaganov/galactus/master/galactus/Assets/Nonstandard%20Assets/Lines.cs
  14.  
  15. [RequireComponent(typeof(Rigidbody))]
  16. public class RBAgent : MonoBehaviour {
  17.     [Serializable]
  18.     public struct CameraControls {
  19.         public Transform eyes;
  20.  
  21.         [Tooltip("If this is set, this agent will accept keyboard and mouse input as controls for velocity")]
  22.         public Camera cam;
  23.         [HideInInspector]
  24.         public RBAgentCamera rbcam;
  25.  
  26.         public float minPitch, maxPitch;
  27.         public float pitch;
  28.         public KeyCode toggleKey;// = KeyCode.None;
  29.  
  30.         public enum KindOfControls { FPS = 1, ClickToMove = 2, None = -1};
  31.  
  32.         public KindOfControls kindOfControls;
  33.         public enum MouseClick { mainClick=0, alternateClick=1, middleClick=2, none = -1}
  34.         public MouseClick clickToMove;
  35.  
  36.         public bool IsUpsidedown { get; private set; }
  37.         [HideInInspector]
  38.         public Quaternion targetForward;
  39.         /// the direction that the user wants to move forward in
  40.         [HideInInspector]
  41.         public Vector3 simpleForward;
  42.  
  43.         public void Init(Transform transform) {
  44.             if(cam != null && eyes != null) {
  45.                 rbcam = cam.GetComponent<RBAgentCamera>();
  46.                 if(rbcam == null) {
  47.                     rbcam = cam.gameObject.AddComponent<RBAgentCamera>();
  48.                 }
  49.                 rbcam.target = eyes;
  50.             }
  51.         }
  52.         public bool RotateBodyToMatchEyes(RBAgent a, bool turnBody) {
  53.             bool bodyRotationMade = false;
  54.             //float f = Mathf.Abs(pitch);
  55.             Vector3 properF = eyes.forward;//(f < 85 || f > 120)? eyes.forward : eyes.up;
  56.             simpleForward = properF.ProjectOntoPlane(a.gravity.Down);
  57.             if(simpleForward == Vector3.zero)
  58.                 simpleForward = properF.ProjectOntoPlane(eyes.up);
  59.             else
  60.                 simpleForward.Normalize();
  61.             targetForward = Quaternion.LookRotation(simpleForward, -a.gravity.Down);
  62.             float toRotateThisFrame = Time.deltaTime * a.Movement.RotationSpeed;
  63.             if(turnBody) {
  64.                 Quaternion lookRotationBeforeBodyShift = eyes.rotation;
  65.                 Quaternion next = Quaternion.RotateTowards(a.transform.rotation, targetForward, toRotateThisFrame);
  66.                 bodyRotationMade = next != a.transform.rotation;
  67.                 if(bodyRotationMade) {
  68.                     a.transform.rotation = next;
  69.                     eyes.rotation = lookRotationBeforeBodyShift;
  70.                 }
  71.             }
  72.             return bodyRotationMade;
  73.         }
  74.         public void UpdatePitch(RBAgent a) {
  75.             pitch = Vector3.Angle(-eyes.up, a.gravity.Down);
  76.             float alignedWithUp = Vector3.Dot(eyes.forward, -a.gravity.Down);
  77.             if(alignedWithUp > 0) pitch *= -1;
  78.             if(minPitch != maxPitch) {
  79.                 if(pitch < minPitch) {
  80.                     eyes.rotation = targetForward; eyes.Rotate(minPitch, 0, 0);
  81.                 }
  82.                 if(pitch > maxPitch) {
  83.                     eyes.rotation = targetForward; eyes.Rotate(maxPitch, 0, 0);
  84.                 }
  85.             }
  86.         }
  87.  
  88.         public void EnumToggle<T>(ref T value, T a, T b) {
  89.             value = (value.Equals(b))?a:b;
  90.         }
  91.        
  92.         public Vector3 GetDirectionBasedOnInput(RBAgent a) {
  93.             Vector3 dir = default(Vector3);
  94.             if(Input.GetKeyDown(toggleKey)) {
  95.                 EnumToggle(ref kindOfControls, KindOfControls.FPS, KindOfControls.ClickToMove);
  96.                 if(clickToMove != MouseClick.none) {
  97.                     a.aiMovement.moveToTarget = kindOfControls == KindOfControls.ClickToMove;
  98.                     if(a.aiMovement.moveToTarget) {
  99.                         a.aiMovement.targetLocation = a.transform.position;
  100.                         rbcam.boundToTargetDirection = false;
  101.                     } else {
  102.                         eyes.rotation = rbcam.transform.rotation;
  103.                         rbcam.boundToTargetDirection = true;
  104.                     }
  105.                 }
  106.             }
  107.             if(kindOfControls == KindOfControls.FPS) {
  108.                 float h = Input.GetAxis("Horizontal"), v = Input.GetAxis("Vertical");
  109.                 if(h != 0 || v != 0) {
  110.                     if(h != 0) { dir += Vector3.Cross(simpleForward, a.gravity.Down) * h; }
  111.                     if(v != 0) { dir += simpleForward * v; }
  112.                     if(!a.gravity.IgnoreGravityPull) {
  113.                         dir = dir.ProjectOntoPlane(a.gravity.Down);
  114.                         dir.Normalize();
  115.                     }
  116.                 }
  117.             } else if(a.aiMovement != null && a.cameraControls.toggleKey != KeyCode.None) {
  118.                 Vector2 mouseDelta = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
  119.                 rbcam.playerTurningCamera = mouseDelta != Vector2.zero;
  120.                 if(rbcam.playerTurningCamera) {
  121.                     RotateCamera(a, mouseDelta);
  122.                 }
  123.             }
  124.             return dir;
  125.         }
  126.         public void RotateCamera(RBAgent a, Vector2 mouse) {
  127.             if(mouse != Vector2.zero) {
  128.                 if(mouse.y != 0) { eyes.Rotate(-mouse.y * a.Movement.CameraTurn, 0, 0); }
  129.                 if(rbcam.distance != 0) { // don't restrict pitch of FPS mode
  130.                     UpdatePitch(a);
  131.                 } else {
  132.                     pitch = eyes.rotation.eulerAngles.x;
  133.                     if(pitch > 180) pitch -= 360;
  134.                 }
  135.                 if(mouse.x != 0) {
  136.                     eyes.Rotate(-pitch, 0, 0);
  137.                     eyes.Rotate(0, mouse.x * a.Movement.CameraTurn, 0);
  138.                     eyes.Rotate(pitch, 0, 0);
  139.                 }
  140.                 RefreshCameraOrientationBasedOnUp(a, eyes);
  141.             }
  142.         }
  143.         public void SetEyeDirectionbasedOnInput(RBAgent a){
  144.             if(kindOfControls == KindOfControls.FPS) {
  145.                 Vector2 mouse = new Vector2(Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y"));
  146.                 RotateCamera(a, mouse);
  147.             }
  148.         }
  149.         public void RefreshCameraOrientationBasedOnUp(RBAgent a, Transform toAlign) {
  150.             float alignedWithUp = Vector3.Dot(-a.gravity.Down, toAlign.up);
  151.             IsUpsidedown = alignedWithUp < 0;
  152.             //Vector3 r = Vector3.Cross(simpleForward, a.gravity.down), angledUp;
  153.             Vector3 r = Vector3.Cross(toAlign.forward, a.gravity.Down), angledUp;
  154.             r.Normalize();
  155.             angledUp = Vector3.Cross(toAlign.forward, r);
  156.             // make sure the camera is oriented correctly
  157.             eyes.rotation = Quaternion.RotateTowards(toAlign.rotation,
  158.                 Quaternion.LookRotation(toAlign.forward, angledUp),
  159.                 a.gravity.GravityTurnSpeed * Time.deltaTime);
  160.             //Debug.Log("ROTATING");
  161.         }
  162.         public void ZoomBasedOnInput(RBAgent a) {
  163.             if(kindOfControls != KindOfControls.None) {
  164.                 float scrollWheel = Input.GetAxis("Mouse ScrollWheel");
  165.                 if(scrollWheel != 0) {
  166.                     rbcam.distance += scrollWheel;
  167.                     if(rbcam.distance < 0) { rbcam.distance = 0; }
  168.                 }
  169.             }
  170.         }
  171.         public void ClickToMove(RBAgent a) {
  172.             if(cam != null && Input.GetMouseButtonDown((int)clickToMove)) {
  173.                 Ray r = cam.ScreenPointToRay(Input.mousePosition);
  174.                 RaycastHit rh = new RaycastHit();
  175.                 if(Physics.Raycast(r, out rh)) {
  176.                     a.aiMovement.targetLocation = rh.point;
  177.                 }
  178.                 if(a.aiMovement.RandomWalk != null) {
  179.                     a.aiMovement.RandomWalk.SetRandomWalkTime(float.NegativeInfinity);
  180.                 }
  181.             }
  182.         }
  183.  
  184.     }
  185.     public CameraControls cameraControls = new CameraControls {
  186.         kindOfControls = CameraControls.KindOfControls.FPS, minPitch=-80, maxPitch=120
  187.     };
  188.  
  189.     [System.Serializable]
  190.     public class AIMovement {
  191.         public bool moveToTarget;
  192.         public Vector3 targetLocation;
  193.  
  194.         /// Gets the direction toward target.
  195.         /// <returns>The direction toward target, or Vector3.zero if agent has arrived</returns>
  196.         /// <param name="a">The alpha component.</param>
  197.         /// <param name="alsoTurn">If set to <c>true</c> also turn.</param>
  198.         public Vector3 GetDirectionTowardTarget(RBAgent a, bool alsoTurn = true) {
  199.             Vector3 delta = targetLocation - a.transform.position;
  200.             if(!a.gravity.IgnoreGravityPull) {
  201.                 delta = delta.ProjectOntoPlane(a.gravity.Down);
  202.                 targetLocation = a.transform.position + delta;
  203.                 if(a.debugLineColor.a > 0) {
  204.                     NS.Lines.MakeCircle(ref a.line_target, targetLocation, a.gravity.Down, a.debugLineColor);
  205.                 }
  206.             }
  207.             float dist = delta.magnitude;
  208.             Vector3 dir = Vector3.zero;
  209.             if(dist != 0) {
  210.                 if(dist < .125f) {
  211.                     if(RandomWalk.Enabled) {
  212.                         RandomWalk.QueueUpdate();
  213.                     } else {
  214.                         return Vector3.zero;
  215.                     }
  216.                 }
  217.                 dir = delta / dist;
  218.                 dir.Normalize();
  219.                 if(alsoTurn) {
  220.                     Quaternion targetRotation = Quaternion.LookRotation(dir, -a.gravity.Down);
  221.                     a.transform.rotation = Quaternion.RotateTowards(a.transform.rotation, targetRotation, Time.deltaTime * a.Movement.RotationSpeed);
  222.                 }
  223.             }
  224.             return dir;
  225.         }
  226.  
  227.         [System.Serializable]
  228.         public class RandomWalkDetails {
  229.             [FormerlySerializedAs("enabled")] public bool Enabled;
  230.             [FormerlySerializedAs("duration")] public float Duration;
  231.             [FormerlySerializedAs("durationWiggleRoom")] public float DurationWiggleRoom;
  232.             private float _timer;
  233.             public void SetRandomWalkTime(float t) { _timer = t; }
  234.             public void Update(Action action) {
  235.                 _timer += Time.deltaTime;
  236.                 if (_timer < Duration) return;
  237.                 _timer -= Duration;
  238.                 _timer -= Random.Range(-DurationWiggleRoom, DurationWiggleRoom);
  239.                 action.Invoke();
  240.             }
  241.             public void QueueUpdate() { _timer = Duration; }
  242.         }
  243.         public RandomWalkDetails RandomWalk = new RandomWalkDetails {
  244.             Enabled = true, Duration = 2, DurationWiggleRoom = 0.5f
  245.         };
  246.     }
  247.     public AIMovement aiMovement = new AIMovement { moveToTarget = true };
  248.  
  249.  
  250.     [Serializable]
  251.     public struct Move {
  252.         [Tooltip("speed of agent")]
  253.         public float Speed;
  254.         [Tooltip("how quickly the body turns (degrees per second)")]
  255.         public float RotationSpeed;
  256.         [Tooltip("how quickly the camera turns (multiplies mouse movement / keyboard input)")]
  257.         public float CameraTurn;
  258.         /// what direction the agent is going in
  259.         [HideInInspector]
  260.         public Vector3 Direction;
  261.     }
  262.     [ContextMenuItem("create move modifier", "CreateMoveModifier")]
  263.     public Move Movement = new Move{Speed = 3, RotationSpeed = 180, CameraTurn = 5 };
  264.  
  265.     private void CreateMoveModifier(){ gameObject.AddComponent<MoveModifier>();}
  266.    
  267.     public class MoveModifier : MonoBehaviour {
  268.         public KeyCode RunKey = KeyCode.LeftShift;
  269.         public float MoveMultiplier = 2; private float _originalSpeed;
  270.         public float MaxStandAngle = 10; private float _originalStandAngle;
  271.         private bool _running;
  272.         private RBAgent _rba;
  273.         void Start() {
  274.             _rba = GetComponent<RBAgent>();
  275.             _originalSpeed = _rba.Movement.Speed;
  276.             _originalStandAngle = _rba.stand.maxStandAngle;
  277.         }
  278.         void Update() {
  279.             bool runningNow = Input.GetKey(RunKey);
  280.             if (runningNow && !_running) {
  281.                 _rba.Movement.Speed = _originalSpeed * MoveMultiplier;
  282.                 _rba.stand.maxStandAngle = MaxStandAngle;
  283.             } else if (!runningNow && _running) {
  284.                 _rba.Movement.Speed = _originalSpeed;
  285.                 _rba.stand.maxStandAngle = _originalStandAngle;
  286.             }
  287.             _running = runningNow;
  288.         }
  289.     }
  290.  
  291.     [System.Serializable]
  292.     public struct Gravity {
  293.         public Vector3 Down;
  294.         public float Force;
  295.         [Tooltip("how quickly to reorient the camera when the direction of gravity changes (degrees per second)")]
  296.         public float GravityTurnSpeed;
  297.         [HideInInspector]
  298.         public float Distance;
  299.         public Vector3 Calculate(RBAgent a, bool a_ignoreGravityPull) {
  300.             if(UseGravityPoint) {
  301.                 Vector3 lastGravity = Down;
  302.                 Down = GravityCenter - a.transform.position;
  303.                 Distance = Down.magnitude;
  304.                 Down /= Distance;
  305.                 if(Down != lastGravity) {
  306.                     Quaternion oldFacing = a.transform.rotation;
  307.                     Transform viewer = (a.cameraControls.kindOfControls == CameraControls.KindOfControls.FPS)
  308.                         ?a.cameraControls.eyes:(a.cameraControls.rbcam.transform
  309.                             ?a.cameraControls.rbcam.transform:null);
  310.                     if(viewer) {
  311.                         Transform oldParent = a.transform;
  312.                         if(viewer.parent != a.transform) {
  313.                             oldParent = viewer.parent;
  314.                             viewer.SetParent(a.transform);
  315.                         }
  316.                         Vector3 localVelocity = Vector3.zero;
  317.                         Quaternion localLook = viewer.localRotation;
  318.                         if(!UseUncurvedVelocity) {
  319.                             localVelocity = a.transform.InverseTransformVector(a.rb.velocity);
  320.                         }
  321.                         Vector3 simpleBodyForward = a.transform.forward.ProjectOntoPlane(Down);
  322.                         simpleBodyForward.Normalize();
  323.                         Quaternion nextIdealBodyFace = Quaternion.LookRotation(simpleBodyForward, -Down);
  324.                         a.transform.rotation = Quaternion.RotateTowards(a.transform.rotation, nextIdealBodyFace, GravityTurnSpeed * Time.deltaTime);
  325.                         if(!UseUncurvedVelocity) {
  326.                             a.rb.velocity = a.transform.TransformVector(localVelocity);
  327.                         }
  328.                         a.cameraControls.RefreshCameraOrientationBasedOnUp(a, viewer);
  329.                         viewer.localRotation = localLook;
  330.                         if(viewer.parent != oldParent) {
  331.                             viewer.SetParent(oldParent);
  332.                         }
  333.                     }
  334.                 }
  335.             } else {
  336.                 Distance = 0;
  337.             }
  338.             if(!IgnoreGravityPull && !a_ignoreGravityPull) {
  339.                 a.rb.velocity += Down * (Force * Time.deltaTime);
  340.             }
  341.             return Down;
  342.         }
  343.         public bool UseGravityPoint;
  344.         public bool IgnoreGravityPull;
  345.         public bool UseUncurvedVelocity;
  346.         public Vector3 GravityCenter;
  347.     }
  348.     public Gravity gravity = new Gravity { Down = Vector3.down, Force = 10, GravityTurnSpeed = 360 };
  349.  
  350.     [System.Serializable]
  351.     public struct Standing {
  352.         public float standAngle;
  353.         public float maxStandAngle;
  354.         public float maxStandHeight;
  355.         public float minStandHeight;
  356.         [HideInInspector]
  357.         public bool IsStanding, IsWalkable;
  358.         public bool wontGrabWalls;
  359.         public bool wontStabalizeFooting;
  360.         public Ray standRay;
  361.         public RaycastHit standHit;
  362.         private Vector3 standOffset, standRayDir;
  363.         public float standRadius;
  364.         public void FixedUpdate(RBAgent a) {
  365.             standRay = new Ray(a.transform.position + standOffset, standRayDir);
  366.             if(Physics.Raycast(standRay, out standHit, maxStandHeight) && standHit.collider.gameObject != a.gameObject) {
  367.                 standAngle = Vector3.Angle(standHit.normal, -a.gravity.Down);
  368.                 IsStanding = standAngle < maxStandAngle;
  369.                 // down hill is a negative stand angle
  370.                 float goingInTheSameDirection = Vector3.Dot(a.GetMoveForward(), standHit.normal);
  371.                 if(goingInTheSameDirection > 0) { standAngle *= -1; }
  372.             } else {
  373.                 standAngle = float.PositiveInfinity;
  374.                 IsStanding = false;
  375.             }
  376.             IsWalkable = standAngle < maxStandAngle;
  377.             if(!IsStanding) {
  378.                 standRayDir = wontGrabWalls? a.gravity.Down :
  379.                                               (a.gravity.Down + Random.insideUnitSphere).normalized + a.cameraControls.simpleForward;
  380.                 standOffset = Random.insideUnitSphere.ProjectOntoPlane(standRayDir) * standRadius;
  381.             }
  382.             if(IsStanding && !a.jump.IsJumping) {
  383.                 if(standHit.distance > minStandHeight) {
  384.                     Vector3 targetLoc = standHit.point - standOffset - standRayDir * minStandHeight;
  385.                     a.transform.position = Vector3.MoveTowards(
  386.                         a.transform.position, targetLoc, a.Movement.Speed * Time.deltaTime);
  387.                 } else if(!wontStabalizeFooting && standRayDir != a.gravity.Down) {
  388.                     standRayDir = a.gravity.Down;
  389.                     Vector3 targetLoc = standHit.point - standOffset - standRayDir * minStandHeight;
  390.                     a.transform.position = Vector3.MoveTowards(
  391.                         a.transform.position, targetLoc, a.Movement.Speed * Time.deltaTime);
  392.                     standRayDir = (standHit.point - (a.transform.position + standOffset)).normalized;
  393.                     standRay = new Ray(a.transform.position + standOffset, standRayDir);
  394.                 }
  395.  
  396.                 float gravityAmount = Vector3.Dot(a.rb.velocity, a.gravity.Down);
  397.                 a.rb.velocity -= a.gravity.Down * gravityAmount;
  398.             }
  399.             if(a.debugLineColor.a > 0) {
  400.                 NS.Lines.Make(ref a.line_dir,
  401.                               a.transform.position + standOffset,
  402.                               a.transform.position + standRayDir * maxStandHeight + standOffset,
  403.                               a.debugLineColor, IsStanding?0.125f:.25f);
  404.             }
  405.         }
  406.     }
  407.     public Standing stand = new Standing { maxStandHeight = 0.75f, minStandHeight = 0.7f, standRadius = 0.5f, maxStandAngle = 45 };
  408.  
  409.     [System.Serializable]
  410.     public struct Jumping {
  411.         public float minJumpHeight, maxJumpHeight;
  412.         [Tooltip("How long the jump button must be pressed to jump the maximum height")]
  413.         public float fullJumpPressDuration;
  414.         [Tooltip("for double-jumping, put a 1 here. To eliminate jumping, put a 0 here.")]
  415.         public int maxJumps;
  416.         /// <summary>Whether or not the jumper wants to press jump (specifically, how many seconds of jump)</summary>
  417.         [HideInInspector]
  418.         public float PressJump;
  419.         private float currentJumpVelocity, heightReached, heightReachedTotal, timeHeld, targetHeight;
  420.         private bool impulseActive, peaked;
  421.         public bool airImpulseAllowed;
  422.  
  423.         public int JumpsSoFar { get; private set; }
  424.         /// <returns>if this instance is trying to jump</returns>
  425.         public bool IsJumping { get { return PressJump > 0; } set { PressJump = value?Time.deltaTime:0; } }
  426.         public void Init(){
  427.             peaked = false;
  428.         }
  429.         /// <summary>pretends to hold the jump button for the specified duration</summary>
  430.         public void FixedUpdate(RBAgent p) {
  431.             bool _isJumping;
  432.             if(_isJumping = (PressJump > 0)) { PressJump -= Time.deltaTime; }
  433.             if(impulseActive && !_isJumping) { impulseActive = false; }
  434.             if(!_isJumping) { return; }
  435.             // check stable footing for the jump
  436.             if(p.stand.IsStanding) {
  437.                 JumpsSoFar = 0;
  438.                 heightReached = 0;
  439.                 currentJumpVelocity = 0;
  440.                 timeHeld = 0;
  441.             }
  442.             // calculate the jump
  443.             float gForce = p.gravity.Force * p.rb.mass;
  444.             Vector3 jump_force = Vector3.zero, jumpDirection = -p.gravity.Down;
  445.             // if the user wants to jump, and is allowed to jump again
  446.             if(!impulseActive && (JumpsSoFar < maxJumps)) {
  447.                 heightReached = 0;
  448.                 timeHeld = 0;
  449.                 JumpsSoFar++;
  450.                 targetHeight = minJumpHeight * p.rb.mass;
  451.                 float velocityRequiredToJump = Mathf.Sqrt(targetHeight * 2 * gForce);
  452.                 // cancel out other current jump/fall forces
  453.                 float motionInVerticalDirection = Vector3.Dot(jumpDirection, p.rb.velocity);
  454.                 jump_force -= (motionInVerticalDirection * jumpDirection) / Time.deltaTime;
  455.                 // apply proper jump force
  456.                 currentJumpVelocity = velocityRequiredToJump;
  457.                 peaked = false;
  458.                 jump_force += (jumpDirection * currentJumpVelocity) / Time.deltaTime;
  459.                 impulseActive = true;
  460.             } else
  461.                 // if a jump is happening      
  462.                 if(currentJumpVelocity > 0) {
  463.                 // handle jump height: the longer you hold jump, the higher you jump
  464.                 if(_isJumping) {
  465.                     timeHeld += Time.deltaTime;
  466.                     if(timeHeld >= fullJumpPressDuration) {
  467.                         targetHeight = maxJumpHeight;
  468.                         timeHeld = fullJumpPressDuration;
  469.                     } else {
  470.                         targetHeight = minJumpHeight + ((maxJumpHeight - minJumpHeight) * timeHeld / fullJumpPressDuration);
  471.                         targetHeight *= p.rb.mass;
  472.                     }
  473.                     if(heightReached < targetHeight) {
  474.                         float requiredJumpVelocity = Mathf.Sqrt((targetHeight - heightReached) * 2 * gForce);
  475.                         float forceNeeded = requiredJumpVelocity - currentJumpVelocity;
  476.                         jump_force += (jumpDirection * forceNeeded) / Time.deltaTime;
  477.                         currentJumpVelocity = requiredJumpVelocity;
  478.                     }
  479.                 }
  480.             } else {
  481.                 impulseActive = false;
  482.             }
  483.             if(currentJumpVelocity > 0) {
  484.                 float moved = currentJumpVelocity * Time.deltaTime;
  485.                 heightReached += moved;
  486.                 heightReachedTotal += moved;
  487.                 currentJumpVelocity -= gForce * Time.deltaTime;
  488.             } else if(!peaked && !p.stand.IsStanding) {
  489.                 peaked = true;
  490.                 impulseActive = false;
  491.             }
  492.             p.rb.AddForce(jump_force);
  493.         }
  494.     }
  495.     public Jumping jump = new Jumping { minJumpHeight = 0.25f, maxJumpHeight = 2, fullJumpPressDuration = 0.5f, maxJumps = 1};
  496.  
  497.     [Tooltip("if clear, will not draw debug lines")]
  498.     public Color debugLineColor = Color.red;
  499.     private Rigidbody rb;
  500.     private GameObject line_target, line_dir;
  501.     private bool shouldRotateBodyToMatchEyes;
  502.  
  503.     public Vector3 GetMoveForward() {
  504.         return cameraControls.eyes != null ? cameraControls.simpleForward : transform.forward;
  505.     }
  506.  
  507.     private void Awake() {
  508.         rb = GetComponent<Rigidbody>();
  509.         rb.freezeRotation = true;
  510.         rb.useGravity = false;
  511.         aiMovement.RandomWalk.QueueUpdate();
  512.         cameraControls.Init(transform);
  513.     }
  514.  
  515.     public void PickANewTarget() {
  516.         Vector3 direction = Random.onUnitSphere;
  517.         if(!gravity.IgnoreGravityPull) {
  518.             direction = direction.ProjectOntoPlane(gravity.Down);
  519.             direction.Normalize();
  520.         }
  521.         aiMovement.targetLocation = transform.position + direction * Movement.Speed * aiMovement.RandomWalk.Duration;
  522.         if(debugLineColor.a > 0) {
  523.             NS.Lines.MakeCircle(ref line_target, aiMovement.targetLocation, gravity.Down, debugLineColor);
  524.         }
  525.     }
  526.  
  527.     private void FixedUpdate() {
  528.         stand.FixedUpdate(this);
  529.         gravity.Calculate(this, stand.IsStanding);
  530.         jump.FixedUpdate(this);
  531.     }
  532.  
  533.     //private void LateUpdate() { cameraControls.LateUpdate(this); }
  534.     void Update () {
  535.         if(cameraControls.cam != null) {
  536.             bool canMove = stand.IsWalkable || jump.airImpulseAllowed;
  537.             if(canMove) {
  538.                 float gravityAmount = (!gravity.IgnoreGravityPull)?Vector3.Dot(rb.velocity, gravity.Down):0;
  539.                 Movement.Direction = cameraControls.GetDirectionBasedOnInput(this);
  540.                 if(Movement.Direction != Vector3.zero) { shouldRotateBodyToMatchEyes = true; }
  541.                 rb.velocity = Movement.Direction * Movement.Speed + gravity.Down * gravityAmount;
  542.             }
  543.             cameraControls.SetEyeDirectionbasedOnInput(this);
  544.             cameraControls.ZoomBasedOnInput(this);
  545.             if(debugLineColor.a > 0) {
  546.                 NS.Lines.MakeCircle(ref line_target, transform.position, cameraControls.eyes.forward, debugLineColor);
  547.             }
  548.             if(Input.GetButton("Jump")) {
  549.                 jump.PressJump = Time.deltaTime;
  550.             }
  551.         }
  552.         if(cameraControls.clickToMove != CameraControls.MouseClick.none) { // TODO move to FixedUpdate?
  553.             cameraControls.ClickToMove(this);
  554.         }
  555.         if(aiMovement.RandomWalk.Enabled) { // TODO move to FixedUpdate?
  556.             aiMovement.RandomWalk.Update(PickANewTarget);
  557.         }
  558.         if(aiMovement.moveToTarget) { // TODO move to FixedUpdate?
  559.             float gravityAmount = (!gravity.IgnoreGravityPull) ? Vector3.Dot(rb.velocity, gravity.Down) : 0;
  560.             Vector3 dir = aiMovement.GetDirectionTowardTarget(this);
  561.             if(dir != Vector3.zero) {
  562.                 rb.velocity = dir * Movement.Speed + gravity.Down * gravityAmount;
  563.             }
  564.             if(debugLineColor.a > 0) {
  565.                 NS.Lines.MakeArrow(ref line_dir, transform.position, transform.position + dir, debugLineColor);
  566.             }
  567.         } else if(cameraControls.eyes != null) {
  568.             shouldRotateBodyToMatchEyes = cameraControls.RotateBodyToMatchEyes(this, shouldRotateBodyToMatchEyes);
  569.         }
  570.     }
  571. }
  572.  
  573. public class RBAgentCamera : MonoBehaviour {
  574.     public Transform target;
  575.     public float distance = 10;
  576.     //private float actualDistance;
  577.     private Vector3 offset;
  578.     //public bool followRotation = true; // behind-shoulder-3rd-person (true) vs overhead-god-view-follow (false)
  579.     public bool boundToTargetDirection = true;
  580.  
  581.     public void Start() {
  582.         offset = new Vector3(0, 0, -distance);
  583.     }
  584.  
  585.     [HideInInspector]
  586.     /// if set to <c>true</c>, use the player's look rotation
  587.     public bool playerTurningCamera;
  588.     public void LateUpdate() {
  589.         if (target == null) return;
  590.         if(!boundToTargetDirection && !playerTurningCamera) {
  591.             target.rotation = transform.rotation;
  592.         }
  593.         transform.rotation = target.rotation;
  594.         RaycastHit rh = new RaycastHit();
  595.         if (Physics.Raycast(target.position, -target.forward, out rh, distance)) {
  596.             offset = target.forward * -rh.distance;
  597.         } else {
  598.             offset = target.forward * -distance;
  599.         }
  600.         transform.position = target.position + offset;
  601.     }
  602. }
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×