You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

105 lines
3.1 KiB

7 years ago
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class CustomSmoothFollow : MonoBehaviour
  5. {
  6. public Transform target;
  7. public float distance = -200.0f;
  8. public float height = 200.0f;
  9. public float altDistance = -100.0f;
  10. public float altHeight = 250.0f;
  11. public Vector3 damping;
  12. public string layerToMask = "CameraObstruct";
  13. private int layerMask;
  14. [Range (0,360)]
  15. public float offsetAngle = 90;
  16. public float shakeStrength = 5f;
  17. private float shakeCurrent;
  18. // Use this for initialization
  19. void Start()
  20. {
  21. layerMask = LayerMask.NameToLayer(layerToMask);
  22. NotificationServer.register("shake camera", shake);
  23. }
  24. // Update is called once per frame
  25. void LateUpdate()
  26. {
  27. // Early out if we don't have a target
  28. if (!target)
  29. return;
  30. // Calculate the current and wanted height / XZ pos
  31. float wantedHeight = target.position.y + height;
  32. float wantedDistance = target.position.z + distance;
  33. float wantedSide = target.position.x;
  34. bool isBlocked = false;
  35. Vector3 wantedPos = new Vector3(wantedSide, wantedHeight, wantedDistance);
  36. wantedPos = RotatePointAroundPivot(wantedPos, target.transform.position, offsetAngle);
  37. RaycastHit hitInfo;
  38. if (Physics.Raycast(wantedPos, target.position-wantedPos, out hitInfo, (target.position-wantedPos).magnitude * 2f))
  39. {
  40. // Debug.LogWarning (hitInfo.collider.name + " -- " + hitInfo.collider.gameObject.layer + " -- " + layerMask);
  41. if (hitInfo.collider.gameObject.layer == layerMask)
  42. isBlocked = true;
  43. }
  44. if (isBlocked)
  45. {
  46. wantedPos.y = target.position.y + altHeight;
  47. wantedPos.z = target.position.z + altDistance;
  48. wantedPos.x = target.position.x;
  49. wantedPos = RotatePointAroundPivot(wantedPos, target.transform.position, offsetAngle);
  50. }
  51. float currentHeight = transform.position.y;
  52. float currentDistance = transform.position.z;
  53. float currentSide = transform.position.x;
  54. // Damp the height
  55. currentHeight = Mathf.Lerp(currentHeight, wantedPos.y, damping.y * Time.deltaTime);
  56. currentDistance = Mathf.Lerp(currentDistance, wantedPos.z, damping.z * Time.deltaTime);
  57. currentSide = Mathf.Lerp(currentSide, wantedPos.x, damping.x * Time.deltaTime);
  58. // Set the position of the camera on the x-z plane to:
  59. // distance meters behind the target
  60. transform.position = target.position;
  61. // Set the height of the camera
  62. transform.position = new Vector3(currentSide, currentHeight, currentDistance);
  63. if (shakeCurrent > 0f)
  64. {
  65. transform.position += Random.insideUnitSphere * shakeStrength;
  66. shakeCurrent -= Time.deltaTime * shakeStrength;
  67. }
  68. // Always look at the target
  69. Vector3 lookTarget = target.position;
  70. lookTarget.z = transform.position.z;
  71. transform.LookAt(lookTarget);
  72. }
  73. public void shake()
  74. {
  75. shakeCurrent = shakeStrength;
  76. }
  77. private Vector3 RotatePointAroundPivot(Vector3 point,Vector3 pivot,float angles ){
  78. Vector3 dir = point - pivot; // get point direction relative to pivot
  79. dir = Quaternion.Euler(angles * Vector3.up) * dir; // rotate it
  80. point = dir + pivot; // calculate rotated point
  81. return point; // return it
  82. }
  83. }