Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using Cinemachine.Utility;// for ProjectOntoPlane
- using UnityEngine.Serialization;
- using Random = UnityEngine.Random;
- // TODO create the RBAgentCamera (and eyes) with a ContextMenuItem, or automatically if the agent is marked as Player
- // TODO ContextMenuItem to create sphere collider
- // TODO fix min/max pitch
- // TODO camera control variables to the RBAgentCamera
- // using Lines drawing code at: https://raw.githubusercontent.com/mvaganov/galactus/master/galactus/Assets/Nonstandard%20Assets/Lines.cs
- [RequireComponent(typeof(Rigidbody))]
- public class RBAgent : MonoBehaviour {
- [Serializable]
- public struct CameraControls {
- public Transform eyes;
- [Tooltip("If this is set, this agent will accept keyboard and mouse input as controls for velocity")]
- public Camera cam;
- [HideInInspector]
- public RBAgentCamera rbcam;
- public float minPitch, maxPitch;
- public float pitch;
- public KeyCode toggleKey;// = KeyCode.None;
- public enum KindOfControls { FPS = 1, ClickToMove = 2, None = -1};
- public KindOfControls kindOfControls;
- public enum MouseClick { mainClick=0, alternateClick=1, middleClick=2, none = -1}
- public MouseClick clickToMove;
- public bool IsUpsidedown { get; private set; }
- [HideInInspector]
- public Quaternion targetForward;
- /// the direction that the user wants to move forward in
- [HideInInspector]
- public Vector3 simpleForward;
- public void Init(Transform transform) {
- if(cam != null && eyes != null) {
- rbcam = cam.GetComponent<RBAgentCamera>();
- if(rbcam == null) {
- rbcam = cam.gameObject.AddComponent<RBAgentCamera>();
- }
- rbcam.target = eyes;
- }
- }
- public bool RotateBodyToMatchEyes(RBAgent a, bool turnBody) {
- bool bodyRotationMade = false;
- //float f = Mathf.Abs(pitch);
- Vector3 properF = eyes.forward;//(f < 85 || f > 120)? eyes.forward : eyes.up;
- simpleForward = properF.ProjectOntoPlane(a.gravity.Down);
- if(simpleForward == Vector3.zero)
- simpleForward = properF.ProjectOntoPlane(eyes.up);
- else
- simpleForward.Normalize();
- targetForward = Quaternion.LookRotation(simpleForward, -a.gravity.Down);
- float toRotateThisFrame = Time.deltaTime * a.Movement.RotationSpeed;
- if(turnBody) {
- Quaternion lookRotationBeforeBodyShift = eyes.rotation;
- Quaternion next = Quaternion.RotateTowards(a.transform.rotation, targetForward, toRotateThisFrame);
- bodyRotationMade = next != a.transform.rotation;
- if(bodyRotationMade) {
- a.transform.rotation = next;
- eyes.rotation = lookRotationBeforeBodyShift;
- }
- }
- return bodyRotationMade;
- }
- public void UpdatePitch(RBAgent a) {
- pitch = Vector3.Angle(-eyes.up, a.gravity.Down);
- float alignedWithUp = Vector3.Dot(eyes.forward, -a.gravity.Down);
- if(alignedWithUp > 0) pitch *= -1;
- if(minPitch != maxPitch) {
- if(pitch < minPitch) {
- eyes.rotation = targetForward; eyes.Rotate(minPitch, 0, 0);
- }
- if(pitch > maxPitch) {
- eyes.rotation = targetForward; eyes.Rotate(maxPitch, 0, 0);
- }
- }
- }
- public void EnumToggle<T>(ref T value, T a, T b) {
- value = (value.Equals(b))?a:b;
- }
- public Vector3 GetDirectionBasedOnInput(RBAgent a) {
- Vector3 dir = default(Vector3);
- if(Input.GetKeyDown(toggleKey)) {
- EnumToggle(ref kindOfControls, KindOfControls.FPS, KindOfControls.ClickToMove);
- if(clickToMove != MouseClick.none) {
- a.aiMovement.moveToTarget = kindOfControls == KindOfControls.ClickToMove;
- if(a.aiMovement.moveToTarget) {
- a.aiMovement.targetLocation = a.transform.position;
- rbcam.boundToTargetDirection = false;
- } else {
- eyes.rotation = rbcam.transform.rotation;
- rbcam.boundToTargetDirection = true;
- }
- }
- }
- if(kindOfControls == KindOfControls.FPS) {
- float h = Input.GetAxis("Horizontal"), v = Input.GetAxis("Vertical");
- if(h != 0 || v != 0) {
- if(h != 0) { dir += Vector3.Cross(simpleForward, a.gravity.Down) * h; }
- if(v != 0) { dir += simpleForward * v; }
- if(!a.gravity.IgnoreGravityPull) {
- dir = dir.ProjectOntoPlane(a.gravity.Down);
- dir.Normalize();
- }
- }
- } else if(a.aiMovement != null && a.cameraControls.toggleKey != KeyCode.None) {
- Vector2 mouseDelta = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
- rbcam.playerTurningCamera = mouseDelta != Vector2.zero;
- if(rbcam.playerTurningCamera) {
- RotateCamera(a, mouseDelta);
- }
- }
- return dir;
- }
- public void RotateCamera(RBAgent a, Vector2 mouse) {
- if(mouse != Vector2.zero) {
- if(mouse.y != 0) { eyes.Rotate(-mouse.y * a.Movement.CameraTurn, 0, 0); }
- if(rbcam.distance != 0) { // don't restrict pitch of FPS mode
- UpdatePitch(a);
- } else {
- pitch = eyes.rotation.eulerAngles.x;
- if(pitch > 180) pitch -= 360;
- }
- if(mouse.x != 0) {
- eyes.Rotate(-pitch, 0, 0);
- eyes.Rotate(0, mouse.x * a.Movement.CameraTurn, 0);
- eyes.Rotate(pitch, 0, 0);
- }
- RefreshCameraOrientationBasedOnUp(a, eyes);
- }
- }
- public void SetEyeDirectionbasedOnInput(RBAgent a){
- if(kindOfControls == KindOfControls.FPS) {
- Vector2 mouse = new Vector2(Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y"));
- RotateCamera(a, mouse);
- }
- }
- public void RefreshCameraOrientationBasedOnUp(RBAgent a, Transform toAlign) {
- float alignedWithUp = Vector3.Dot(-a.gravity.Down, toAlign.up);
- IsUpsidedown = alignedWithUp < 0;
- //Vector3 r = Vector3.Cross(simpleForward, a.gravity.down), angledUp;
- Vector3 r = Vector3.Cross(toAlign.forward, a.gravity.Down), angledUp;
- r.Normalize();
- angledUp = Vector3.Cross(toAlign.forward, r);
- // make sure the camera is oriented correctly
- eyes.rotation = Quaternion.RotateTowards(toAlign.rotation,
- Quaternion.LookRotation(toAlign.forward, angledUp),
- a.gravity.GravityTurnSpeed * Time.deltaTime);
- //Debug.Log("ROTATING");
- }
- public void ZoomBasedOnInput(RBAgent a) {
- if(kindOfControls != KindOfControls.None) {
- float scrollWheel = Input.GetAxis("Mouse ScrollWheel");
- if(scrollWheel != 0) {
- rbcam.distance += scrollWheel;
- if(rbcam.distance < 0) { rbcam.distance = 0; }
- }
- }
- }
- public void ClickToMove(RBAgent a) {
- if(cam != null && Input.GetMouseButtonDown((int)clickToMove)) {
- Ray r = cam.ScreenPointToRay(Input.mousePosition);
- RaycastHit rh = new RaycastHit();
- if(Physics.Raycast(r, out rh)) {
- a.aiMovement.targetLocation = rh.point;
- }
- if(a.aiMovement.RandomWalk != null) {
- a.aiMovement.RandomWalk.SetRandomWalkTime(float.NegativeInfinity);
- }
- }
- }
- }
- public CameraControls cameraControls = new CameraControls {
- kindOfControls = CameraControls.KindOfControls.FPS, minPitch=-80, maxPitch=120
- };
- [System.Serializable]
- public class AIMovement {
- public bool moveToTarget;
- public Vector3 targetLocation;
- /// Gets the direction toward target.
- /// <returns>The direction toward target, or Vector3.zero if agent has arrived</returns>
- /// <param name="a">The alpha component.</param>
- /// <param name="alsoTurn">If set to <c>true</c> also turn.</param>
- public Vector3 GetDirectionTowardTarget(RBAgent a, bool alsoTurn = true) {
- Vector3 delta = targetLocation - a.transform.position;
- if(!a.gravity.IgnoreGravityPull) {
- delta = delta.ProjectOntoPlane(a.gravity.Down);
- targetLocation = a.transform.position + delta;
- if(a.debugLineColor.a > 0) {
- NS.Lines.MakeCircle(ref a.line_target, targetLocation, a.gravity.Down, a.debugLineColor);
- }
- }
- float dist = delta.magnitude;
- Vector3 dir = Vector3.zero;
- if(dist != 0) {
- if(dist < .125f) {
- if(RandomWalk.Enabled) {
- RandomWalk.QueueUpdate();
- } else {
- return Vector3.zero;
- }
- }
- dir = delta / dist;
- dir.Normalize();
- if(alsoTurn) {
- Quaternion targetRotation = Quaternion.LookRotation(dir, -a.gravity.Down);
- a.transform.rotation = Quaternion.RotateTowards(a.transform.rotation, targetRotation, Time.deltaTime * a.Movement.RotationSpeed);
- }
- }
- return dir;
- }
- [System.Serializable]
- public class RandomWalkDetails {
- [FormerlySerializedAs("enabled")] public bool Enabled;
- [FormerlySerializedAs("duration")] public float Duration;
- [FormerlySerializedAs("durationWiggleRoom")] public float DurationWiggleRoom;
- private float _timer;
- public void SetRandomWalkTime(float t) { _timer = t; }
- public void Update(Action action) {
- _timer += Time.deltaTime;
- if (_timer < Duration) return;
- _timer -= Duration;
- _timer -= Random.Range(-DurationWiggleRoom, DurationWiggleRoom);
- action.Invoke();
- }
- public void QueueUpdate() { _timer = Duration; }
- }
- public RandomWalkDetails RandomWalk = new RandomWalkDetails {
- Enabled = true, Duration = 2, DurationWiggleRoom = 0.5f
- };
- }
- public AIMovement aiMovement = new AIMovement { moveToTarget = true };
- [Serializable]
- public struct Move {
- [Tooltip("speed of agent")]
- public float Speed;
- [Tooltip("how quickly the body turns (degrees per second)")]
- public float RotationSpeed;
- [Tooltip("how quickly the camera turns (multiplies mouse movement / keyboard input)")]
- public float CameraTurn;
- /// what direction the agent is going in
- [HideInInspector]
- public Vector3 Direction;
- }
- [ContextMenuItem("create move modifier", "CreateMoveModifier")]
- public Move Movement = new Move{Speed = 3, RotationSpeed = 180, CameraTurn = 5 };
- private void CreateMoveModifier(){ gameObject.AddComponent<MoveModifier>();}
- public class MoveModifier : MonoBehaviour {
- public KeyCode RunKey = KeyCode.LeftShift;
- public float MoveMultiplier = 2; private float _originalSpeed;
- public float MaxStandAngle = 10; private float _originalStandAngle;
- private bool _running;
- private RBAgent _rba;
- void Start() {
- _rba = GetComponent<RBAgent>();
- _originalSpeed = _rba.Movement.Speed;
- _originalStandAngle = _rba.stand.maxStandAngle;
- }
- void Update() {
- bool runningNow = Input.GetKey(RunKey);
- if (runningNow && !_running) {
- _rba.Movement.Speed = _originalSpeed * MoveMultiplier;
- _rba.stand.maxStandAngle = MaxStandAngle;
- } else if (!runningNow && _running) {
- _rba.Movement.Speed = _originalSpeed;
- _rba.stand.maxStandAngle = _originalStandAngle;
- }
- _running = runningNow;
- }
- }
- [System.Serializable]
- public struct Gravity {
- public Vector3 Down;
- public float Force;
- [Tooltip("how quickly to reorient the camera when the direction of gravity changes (degrees per second)")]
- public float GravityTurnSpeed;
- [HideInInspector]
- public float Distance;
- public Vector3 Calculate(RBAgent a, bool a_ignoreGravityPull) {
- if(UseGravityPoint) {
- Vector3 lastGravity = Down;
- Down = GravityCenter - a.transform.position;
- Distance = Down.magnitude;
- Down /= Distance;
- if(Down != lastGravity) {
- Quaternion oldFacing = a.transform.rotation;
- Transform viewer = (a.cameraControls.kindOfControls == CameraControls.KindOfControls.FPS)
- ?a.cameraControls.eyes:(a.cameraControls.rbcam.transform
- ?a.cameraControls.rbcam.transform:null);
- if(viewer) {
- Transform oldParent = a.transform;
- if(viewer.parent != a.transform) {
- oldParent = viewer.parent;
- viewer.SetParent(a.transform);
- }
- Vector3 localVelocity = Vector3.zero;
- Quaternion localLook = viewer.localRotation;
- if(!UseUncurvedVelocity) {
- localVelocity = a.transform.InverseTransformVector(a.rb.velocity);
- }
- Vector3 simpleBodyForward = a.transform.forward.ProjectOntoPlane(Down);
- simpleBodyForward.Normalize();
- Quaternion nextIdealBodyFace = Quaternion.LookRotation(simpleBodyForward, -Down);
- a.transform.rotation = Quaternion.RotateTowards(a.transform.rotation, nextIdealBodyFace, GravityTurnSpeed * Time.deltaTime);
- if(!UseUncurvedVelocity) {
- a.rb.velocity = a.transform.TransformVector(localVelocity);
- }
- a.cameraControls.RefreshCameraOrientationBasedOnUp(a, viewer);
- viewer.localRotation = localLook;
- if(viewer.parent != oldParent) {
- viewer.SetParent(oldParent);
- }
- }
- }
- } else {
- Distance = 0;
- }
- if(!IgnoreGravityPull && !a_ignoreGravityPull) {
- a.rb.velocity += Down * (Force * Time.deltaTime);
- }
- return Down;
- }
- public bool UseGravityPoint;
- public bool IgnoreGravityPull;
- public bool UseUncurvedVelocity;
- public Vector3 GravityCenter;
- }
- public Gravity gravity = new Gravity { Down = Vector3.down, Force = 10, GravityTurnSpeed = 360 };
- [System.Serializable]
- public struct Standing {
- public float standAngle;
- public float maxStandAngle;
- public float maxStandHeight;
- public float minStandHeight;
- [HideInInspector]
- public bool IsStanding, IsWalkable;
- public bool wontGrabWalls;
- public bool wontStabalizeFooting;
- public Ray standRay;
- public RaycastHit standHit;
- private Vector3 standOffset, standRayDir;
- public float standRadius;
- public void FixedUpdate(RBAgent a) {
- standRay = new Ray(a.transform.position + standOffset, standRayDir);
- if(Physics.Raycast(standRay, out standHit, maxStandHeight) && standHit.collider.gameObject != a.gameObject) {
- standAngle = Vector3.Angle(standHit.normal, -a.gravity.Down);
- IsStanding = standAngle < maxStandAngle;
- // down hill is a negative stand angle
- float goingInTheSameDirection = Vector3.Dot(a.GetMoveForward(), standHit.normal);
- if(goingInTheSameDirection > 0) { standAngle *= -1; }
- } else {
- standAngle = float.PositiveInfinity;
- IsStanding = false;
- }
- IsWalkable = standAngle < maxStandAngle;
- if(!IsStanding) {
- standRayDir = wontGrabWalls? a.gravity.Down :
- (a.gravity.Down + Random.insideUnitSphere).normalized + a.cameraControls.simpleForward;
- standOffset = Random.insideUnitSphere.ProjectOntoPlane(standRayDir) * standRadius;
- }
- if(IsStanding && !a.jump.IsJumping) {
- if(standHit.distance > minStandHeight) {
- Vector3 targetLoc = standHit.point - standOffset - standRayDir * minStandHeight;
- a.transform.position = Vector3.MoveTowards(
- a.transform.position, targetLoc, a.Movement.Speed * Time.deltaTime);
- } else if(!wontStabalizeFooting && standRayDir != a.gravity.Down) {
- standRayDir = a.gravity.Down;
- Vector3 targetLoc = standHit.point - standOffset - standRayDir * minStandHeight;
- a.transform.position = Vector3.MoveTowards(
- a.transform.position, targetLoc, a.Movement.Speed * Time.deltaTime);
- standRayDir = (standHit.point - (a.transform.position + standOffset)).normalized;
- standRay = new Ray(a.transform.position + standOffset, standRayDir);
- }
- float gravityAmount = Vector3.Dot(a.rb.velocity, a.gravity.Down);
- a.rb.velocity -= a.gravity.Down * gravityAmount;
- }
- if(a.debugLineColor.a > 0) {
- NS.Lines.Make(ref a.line_dir,
- a.transform.position + standOffset,
- a.transform.position + standRayDir * maxStandHeight + standOffset,
- a.debugLineColor, IsStanding?0.125f:.25f);
- }
- }
- }
- public Standing stand = new Standing { maxStandHeight = 0.75f, minStandHeight = 0.7f, standRadius = 0.5f, maxStandAngle = 45 };
- [System.Serializable]
- public struct Jumping {
- public float minJumpHeight, maxJumpHeight;
- [Tooltip("How long the jump button must be pressed to jump the maximum height")]
- public float fullJumpPressDuration;
- [Tooltip("for double-jumping, put a 1 here. To eliminate jumping, put a 0 here.")]
- public int maxJumps;
- /// <summary>Whether or not the jumper wants to press jump (specifically, how many seconds of jump)</summary>
- [HideInInspector]
- public float PressJump;
- private float currentJumpVelocity, heightReached, heightReachedTotal, timeHeld, targetHeight;
- private bool impulseActive, peaked;
- public bool airImpulseAllowed;
- public int JumpsSoFar { get; private set; }
- /// <returns>if this instance is trying to jump</returns>
- public bool IsJumping { get { return PressJump > 0; } set { PressJump = value?Time.deltaTime:0; } }
- public void Init(){
- peaked = false;
- }
- /// <summary>pretends to hold the jump button for the specified duration</summary>
- public void FixedUpdate(RBAgent p) {
- bool _isJumping;
- if(_isJumping = (PressJump > 0)) { PressJump -= Time.deltaTime; }
- if(impulseActive && !_isJumping) { impulseActive = false; }
- if(!_isJumping) { return; }
- // check stable footing for the jump
- if(p.stand.IsStanding) {
- JumpsSoFar = 0;
- heightReached = 0;
- currentJumpVelocity = 0;
- timeHeld = 0;
- }
- // calculate the jump
- float gForce = p.gravity.Force * p.rb.mass;
- Vector3 jump_force = Vector3.zero, jumpDirection = -p.gravity.Down;
- // if the user wants to jump, and is allowed to jump again
- if(!impulseActive && (JumpsSoFar < maxJumps)) {
- heightReached = 0;
- timeHeld = 0;
- JumpsSoFar++;
- targetHeight = minJumpHeight * p.rb.mass;
- float velocityRequiredToJump = Mathf.Sqrt(targetHeight * 2 * gForce);
- // cancel out other current jump/fall forces
- float motionInVerticalDirection = Vector3.Dot(jumpDirection, p.rb.velocity);
- jump_force -= (motionInVerticalDirection * jumpDirection) / Time.deltaTime;
- // apply proper jump force
- currentJumpVelocity = velocityRequiredToJump;
- peaked = false;
- jump_force += (jumpDirection * currentJumpVelocity) / Time.deltaTime;
- impulseActive = true;
- } else
- // if a jump is happening
- if(currentJumpVelocity > 0) {
- // handle jump height: the longer you hold jump, the higher you jump
- if(_isJumping) {
- timeHeld += Time.deltaTime;
- if(timeHeld >= fullJumpPressDuration) {
- targetHeight = maxJumpHeight;
- timeHeld = fullJumpPressDuration;
- } else {
- targetHeight = minJumpHeight + ((maxJumpHeight - minJumpHeight) * timeHeld / fullJumpPressDuration);
- targetHeight *= p.rb.mass;
- }
- if(heightReached < targetHeight) {
- float requiredJumpVelocity = Mathf.Sqrt((targetHeight - heightReached) * 2 * gForce);
- float forceNeeded = requiredJumpVelocity - currentJumpVelocity;
- jump_force += (jumpDirection * forceNeeded) / Time.deltaTime;
- currentJumpVelocity = requiredJumpVelocity;
- }
- }
- } else {
- impulseActive = false;
- }
- if(currentJumpVelocity > 0) {
- float moved = currentJumpVelocity * Time.deltaTime;
- heightReached += moved;
- heightReachedTotal += moved;
- currentJumpVelocity -= gForce * Time.deltaTime;
- } else if(!peaked && !p.stand.IsStanding) {
- peaked = true;
- impulseActive = false;
- }
- p.rb.AddForce(jump_force);
- }
- }
- public Jumping jump = new Jumping { minJumpHeight = 0.25f, maxJumpHeight = 2, fullJumpPressDuration = 0.5f, maxJumps = 1};
- [Tooltip("if clear, will not draw debug lines")]
- public Color debugLineColor = Color.red;
- private Rigidbody rb;
- private GameObject line_target, line_dir;
- private bool shouldRotateBodyToMatchEyes;
- public Vector3 GetMoveForward() {
- return cameraControls.eyes != null ? cameraControls.simpleForward : transform.forward;
- }
- private void Awake() {
- rb = GetComponent<Rigidbody>();
- rb.freezeRotation = true;
- rb.useGravity = false;
- aiMovement.RandomWalk.QueueUpdate();
- cameraControls.Init(transform);
- }
- public void PickANewTarget() {
- Vector3 direction = Random.onUnitSphere;
- if(!gravity.IgnoreGravityPull) {
- direction = direction.ProjectOntoPlane(gravity.Down);
- direction.Normalize();
- }
- aiMovement.targetLocation = transform.position + direction * Movement.Speed * aiMovement.RandomWalk.Duration;
- if(debugLineColor.a > 0) {
- NS.Lines.MakeCircle(ref line_target, aiMovement.targetLocation, gravity.Down, debugLineColor);
- }
- }
- private void FixedUpdate() {
- stand.FixedUpdate(this);
- gravity.Calculate(this, stand.IsStanding);
- jump.FixedUpdate(this);
- }
- //private void LateUpdate() { cameraControls.LateUpdate(this); }
- void Update () {
- if(cameraControls.cam != null) {
- bool canMove = stand.IsWalkable || jump.airImpulseAllowed;
- if(canMove) {
- float gravityAmount = (!gravity.IgnoreGravityPull)?Vector3.Dot(rb.velocity, gravity.Down):0;
- Movement.Direction = cameraControls.GetDirectionBasedOnInput(this);
- if(Movement.Direction != Vector3.zero) { shouldRotateBodyToMatchEyes = true; }
- rb.velocity = Movement.Direction * Movement.Speed + gravity.Down * gravityAmount;
- }
- cameraControls.SetEyeDirectionbasedOnInput(this);
- cameraControls.ZoomBasedOnInput(this);
- if(debugLineColor.a > 0) {
- NS.Lines.MakeCircle(ref line_target, transform.position, cameraControls.eyes.forward, debugLineColor);
- }
- if(Input.GetButton("Jump")) {
- jump.PressJump = Time.deltaTime;
- }
- }
- if(cameraControls.clickToMove != CameraControls.MouseClick.none) { // TODO move to FixedUpdate?
- cameraControls.ClickToMove(this);
- }
- if(aiMovement.RandomWalk.Enabled) { // TODO move to FixedUpdate?
- aiMovement.RandomWalk.Update(PickANewTarget);
- }
- if(aiMovement.moveToTarget) { // TODO move to FixedUpdate?
- float gravityAmount = (!gravity.IgnoreGravityPull) ? Vector3.Dot(rb.velocity, gravity.Down) : 0;
- Vector3 dir = aiMovement.GetDirectionTowardTarget(this);
- if(dir != Vector3.zero) {
- rb.velocity = dir * Movement.Speed + gravity.Down * gravityAmount;
- }
- if(debugLineColor.a > 0) {
- NS.Lines.MakeArrow(ref line_dir, transform.position, transform.position + dir, debugLineColor);
- }
- } else if(cameraControls.eyes != null) {
- shouldRotateBodyToMatchEyes = cameraControls.RotateBodyToMatchEyes(this, shouldRotateBodyToMatchEyes);
- }
- }
- }
- public class RBAgentCamera : MonoBehaviour {
- public Transform target;
- public float distance = 10;
- //private float actualDistance;
- private Vector3 offset;
- //public bool followRotation = true; // behind-shoulder-3rd-person (true) vs overhead-god-view-follow (false)
- public bool boundToTargetDirection = true;
- public void Start() {
- offset = new Vector3(0, 0, -distance);
- }
- [HideInInspector]
- /// if set to <c>true</c>, use the player's look rotation
- public bool playerTurningCamera;
- public void LateUpdate() {
- if (target == null) return;
- if(!boundToTargetDirection && !playerTurningCamera) {
- target.rotation = transform.rotation;
- }
- transform.rotation = target.rotation;
- RaycastHit rh = new RaycastHit();
- if (Physics.Raycast(target.position, -target.forward, out rh, distance)) {
- offset = target.forward * -rh.distance;
- } else {
- offset = target.forward * -distance;
- }
- transform.position = target.position + offset;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement