Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System.Collections.Generic;
- using Unity.VisualScripting;
- using UnityEngine;
- using UnityEngine.Animations.Rigging;
- public class LookAtTarget : MonoBehaviour
- {
- public List<Transform> lookObjects = new List<Transform>();
- public float weightDamping = 1.5f;
- public float rotationSpeed = 5f;
- public bool fingerPointing = true;
- private InteractableItem interactableItem;
- private Animator animator;
- private Transform lastPrimaryTarget;
- private float finalLookWeight = 0;
- private bool transitionToNextTarget = false;
- private Quaternion restRotation;
- public Transform eyeLeft; // Assign rig_eye.L in the inspector
- public Transform eyeRight; // Assign rig_eye.R in the inspector
- public Transform finger; // Assign the finger bone in the inspector
- private LineRenderer leftEyeLineRenderer;
- private LineRenderer rightEyeLineRenderer;
- private LineRenderer fingerLineRenderer;
- private float LayerWeightTarget = 0;
- private float CurrentLayerWeight = 0;
- private int layerIndex = 0;
- void Start()
- {
- animator = GetComponent<Animator>();
- restRotation = transform.rotation;
- lastPrimaryTarget = null;
- // Initialize and set up the LineRenderers for the eyes and finger
- leftEyeLineRenderer = eyeLeft.gameObject.AddComponent<LineRenderer>();
- rightEyeLineRenderer = eyeRight.gameObject.AddComponent<LineRenderer>();
- fingerLineRenderer = finger.gameObject.AddComponent<LineRenderer>();
- SetUpLineRenderer(leftEyeLineRenderer, Color.yellow);
- SetUpLineRenderer(rightEyeLineRenderer, Color.yellow);
- SetUpLineRenderer(fingerLineRenderer, Color.blue);
- // Initially disable the LineRenderers
- leftEyeLineRenderer.enabled = false;
- rightEyeLineRenderer.enabled = false;
- fingerLineRenderer.enabled = false;
- }
- private void Update()
- {
- // Determine if the character should be pointing
- bool shouldPoint = lastPrimaryTarget != null && fingerPointing;
- LayerWeightTarget = shouldPoint ? 1.0f : 0.0f;
- // Update the current layer weight towards the target weight
- if (Mathf.Abs(CurrentLayerWeight - LayerWeightTarget) > 0.01f) // Adding a threshold to prevent continuous updates
- {
- CurrentLayerWeight += (LayerWeightTarget - CurrentLayerWeight) * 0.125f; // Smoothing the transition
- animator.SetLayerWeight(layerIndex, CurrentLayerWeight);
- }
- }
- private void SetUpLineRenderer(LineRenderer lineRenderer, Color color)
- {
- // Create a simple unlit material that supports vertex colors
- Material lineMaterial = new Material(Shader.Find("Sprites/Default"));
- lineRenderer.material = lineMaterial;
- lineRenderer.startColor = color;
- lineRenderer.endColor = color;
- lineRenderer.startWidth = 0.01f;
- lineRenderer.endWidth = 0.01f;
- }
- void OnAnimatorIK()
- {
- Transform primaryTarget = null;
- float closestDistance = float.MaxValue;
- foreach (Transform target in lookObjects)
- {
- Vector3 toTarget = target.position - transform.position;
- float distance = toTarget.sqrMagnitude;
- if (distance < closestDistance && IsTargetVisible(target))
- {
- closestDistance = distance;
- primaryTarget = target;
- interactableItem = target.GetComponent<InteractableItem>();
- }
- }
- animator.SetBool("Pointing", true);
- ManageLookTransition(primaryTarget);
- if (!fingerPointing && animator.GetBool("Pointing"))
- {
- animator.SetBool("Pointing", false);
- }
- }
- private bool IsTargetVisible(Transform target)
- {
- Vector3 toTarget = (target.position - transform.position).normalized;
- float dotProduct = Vector3.Dot(transform.forward, toTarget);
- return dotProduct > 0;
- }
- private void ManageLookTransition(Transform primaryTarget)
- {
- // If we have a primary target...
- if (primaryTarget != null)
- {
- // Enable the LineRenderers for the eyes
- leftEyeLineRenderer.enabled = true;
- rightEyeLineRenderer.enabled = true;
- // Draw lines from the eyes to the target
- leftEyeLineRenderer.SetPosition(0, eyeLeft.position);
- leftEyeLineRenderer.SetPosition(1, primaryTarget.position);
- rightEyeLineRenderer.SetPosition(0, eyeRight.position);
- rightEyeLineRenderer.SetPosition(1, primaryTarget.position);
- // Manage pointing state and animation
- if (fingerPointing)
- {
- // Ensure the Pointing layer is fully influencing the character's animation
- animator.SetLayerWeight(1, 1.0f); // Assuming layer 1 is the Pointing layer
- animator.SetBool("Pointing", true);
- // Enable and draw the line from the finger to the target
- fingerLineRenderer.enabled = true;
- fingerLineRenderer.SetPosition(0, finger.position);
- fingerLineRenderer.SetPosition(1, primaryTarget.position);
- }
- // Update and display text from the new target
- UpdateInteractableDisplay(primaryTarget);
- // Update the last primary target
- lastPrimaryTarget = primaryTarget;
- // Smoothly blend the look at weight.
- finalLookWeight = Mathf.Lerp(finalLookWeight, 1f, Time.deltaTime * weightDamping);
- animator.SetLookAtWeight(finalLookWeight, finalLookWeight * .75f, 1f);
- animator.SetLookAtPosition(primaryTarget.position);
- }
- else
- {
- // Disable LineRenderers and pointing animation
- DisablePointingState();
- // If we don't have a primary target, disable the LineRenderers
- leftEyeLineRenderer.enabled = false;
- rightEyeLineRenderer.enabled = false;
- fingerLineRenderer.enabled = false;
- // If we don't have a primary target and we were pointing...
- if (animator.GetBool("Pointing"))
- {
- // ... then stop pointing and hide the text.
- animator.SetBool("Pointing", false);
- UIManager.Instance.HideInteractableText();
- }
- // If the look weight is greater than 0, or we are transitioning to the next target...
- if (finalLookWeight > 0f || transitionToNextTarget)
- {
- // ... then blend the look weight back to 0.
- finalLookWeight = Mathf.Lerp(finalLookWeight, 0f, Time.deltaTime * weightDamping);
- animator.SetLookAtWeight(finalLookWeight, finalLookWeight * .75f, 1f);
- // If the last primary target is still set, update the look at position.
- if (lastPrimaryTarget != null)
- {
- animator.SetLookAtPosition(lastPrimaryTarget.position);
- }
- }
- // If we are in the middle of a transition...
- if (transitionToNextTarget)
- {
- // ... then slerp back to the rest rotation.
- transform.rotation = Quaternion.Slerp(transform.rotation, restRotation, rotationSpeed * Time.deltaTime);
- // If we're close to the rest rotation...
- if (Quaternion.Angle(transform.rotation, restRotation) < 1f)
- {
- // ... end the transition and clear the last primary target.
- transitionToNextTarget = false;
- lastPrimaryTarget = null;
- }
- }
- }
- }
- private void UpdateInteractableDisplay(Transform target)
- {
- InteractableItem interactable = target.GetComponent<InteractableItem>();
- if (interactable != null)
- {
- UIManager.Instance.ShowInteractableText(interactable.displayText);
- }
- }
- private void DisablePointingState()
- {
- leftEyeLineRenderer.enabled = false;
- rightEyeLineRenderer.enabled = false;
- fingerLineRenderer.enabled = false;
- UIManager.Instance.HideInteractableText();
- // Turn off the pointing animations
- animator.SetBool("Pointing", false);
- animator.SetLayerWeight(1, 0.0f); // Reduce the Pointing layer's influence
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment