Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
12 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by Tony_T · Feb 05, 2017 at 08:14 PM · lookatmouse cursor

Look At Mouse Cursor Instead Of Object

Hello, I'm using the HeadLookControll script by Unity but I'm trying to change the code a bit. The first script has a variable public Vector3 target = Vector3.zero; and this line Vector3 lookDirWorld = (target - segment.lastTransform.position).normalized;I'm not sure but i think it makes the character look at the target. This is the second script that you attach to an empty object (the object that the character will look at) so that the first script can work.

 using UnityEngine;
 using System.Collections;
 
 public class CursorHit : MonoBehaviour 
 {
 
 public HeadLookController headLook;
 private float offset = 1.5f;
     
 void LateUpdate () 
 {
     if (Input.GetKey(KeyCode.UpArrow))
     offset += Time.deltaTime;
     
     if (Input.GetKey(KeyCode.DownArrow))
     offset -= Time.deltaTime;
         
     Ray cursorRay = Camera.main.ScreenPointToRay(Input.mousePosition);
     RaycastHit hit;
         if (Physics.Raycast(cursorRay, out hit)) 
         {
         transform.position = hit.point + offset * Vector3.down;
         }
         
         headLook.target = transform.position;
     }
 }

What i want to achieve is remove the second script because i want the character to follow the mouse cursor not an object by changing a line in the first script without using 2 different script.

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by Tony_T · Feb 06, 2017 at 04:18 PM

I found a solution, now it follows the mouse cursor and it doesn't require 2 scripts (You don't need CursorHit.cs). Here is the tweaked version of the HeadLookController for anyone that wants it:

 using UnityEngine;
 using System.Collections;
 
 [System.Serializable]
 public class BendingSegment {
     public Transform firstTransform;
     public Transform lastTransform;
     public float thresholdAngleDifference = 0;
     public float bendingMultiplier = 0.6f;
     public float maxAngleDifference = 30;
     public float maxBendingAngle = 80;
     public float responsiveness = 5;
     internal float angleH;
     internal float angleV;
     internal Vector3 dirUp;
     internal Vector3 referenceLookDir;
     internal Vector3 referenceUpDir;
     internal int chainLength;
     internal Quaternion[] origRotations;
 }
 
 [System.Serializable]
 public class NonAffectedJoints {
     public Transform joint;
     public float effect = 0;
 }
 
 public class HeadLookController : MonoBehaviour {
     private float offset = 1.5f;
     private Vector3 MouseCursor;
     public Transform rootNode;
     public BendingSegment[] segments;
     public NonAffectedJoints[] nonAffectedJoints;
     public Vector3 headLookVector = Vector3.forward;
     public Vector3 headUpVector = Vector3.up;
     public Vector3 target = Vector3.zero;
     public float effect = 1;
     public bool overrideAnimation = false;
     
     void Start () {
         if (rootNode == null) {
             rootNode = transform;
         }
         
         // Setup segments
         foreach (BendingSegment segment in segments) {
             Quaternion parentRot = segment.firstTransform.parent.rotation;
             Quaternion parentRotInv = Quaternion.Inverse(parentRot);
             segment.referenceLookDir =
                 parentRotInv * rootNode.rotation * headLookVector.normalized;
             segment.referenceUpDir =
                 parentRotInv * rootNode.rotation * headUpVector.normalized;
             segment.angleH = 0;
             segment.angleV = 0;
             segment.dirUp = segment.referenceUpDir;
             
             segment.chainLength = 1;
             Transform t = segment.lastTransform;
             while (t != segment.firstTransform && t != t.root) {
                 segment.chainLength++;
                 t = t.parent;
             }
             
             segment.origRotations = new Quaternion[segment.chainLength];
             t = segment.lastTransform;
             for (int i=segment.chainLength-1; i>=0; i--) {
                 segment.origRotations[i] = t.localRotation;
                 t = t.parent;
             }
         }
     }
     
     void LateUpdate () {
         if (Time.deltaTime == 0)
             return;
         
         // Remember initial directions of joints that should not be affected
         Vector3[] jointDirections = new Vector3[nonAffectedJoints.Length];
         for (int i=0; i<nonAffectedJoints.Length; i++) {
             foreach (Transform child in nonAffectedJoints[i].joint) {
                 jointDirections[i] = child.position - nonAffectedJoints[i].joint.position;
                 break;
             }
         }
         
         // Handle each segment
         foreach (BendingSegment segment in segments) {
             Transform t = segment.lastTransform;
             if (overrideAnimation) {
                 for (int i=segment.chainLength-1; i>=0; i--) {
                     t.localRotation = segment.origRotations[i];
                     t = t.parent;
                 }
             }
             
             Quaternion parentRot = segment.firstTransform.parent.rotation;
             Quaternion parentRotInv = Quaternion.Inverse(parentRot);
             
             // Desired look direction in world space
             Vector3 lookDirWorld = (target - segment.lastTransform.position).normalized;
             
             // Desired look directions in neck parent space
             Vector3 lookDirGoal = (parentRotInv * lookDirWorld);
             
             // Get the horizontal and vertical rotation angle to look at the target
             float hAngle = AngleAroundAxis(
                 segment.referenceLookDir, lookDirGoal, segment.referenceUpDir
             );
             
             Vector3 rightOfTarget = Vector3.Cross(segment.referenceUpDir, lookDirGoal);
             
             Vector3 lookDirGoalinHPlane =
                 lookDirGoal - Vector3.Project(lookDirGoal, segment.referenceUpDir);
             
             float vAngle = AngleAroundAxis(
                 lookDirGoalinHPlane, lookDirGoal, rightOfTarget
             );
             
             // Handle threshold angle difference, bending multiplier,
             // and max angle difference here
             float hAngleThr = Mathf.Max(
                 0, Mathf.Abs(hAngle) - segment.thresholdAngleDifference
             ) * Mathf.Sign(hAngle);
             
             float vAngleThr = Mathf.Max(
                 0, Mathf.Abs(vAngle) - segment.thresholdAngleDifference
             ) * Mathf.Sign(vAngle);
             
             hAngle = Mathf.Max(
                 Mathf.Abs(hAngleThr) * Mathf.Abs(segment.bendingMultiplier),
                 Mathf.Abs(hAngle) - segment.maxAngleDifference
             ) * Mathf.Sign(hAngle) * Mathf.Sign(segment.bendingMultiplier);
             
             vAngle = Mathf.Max(
                 Mathf.Abs(vAngleThr) * Mathf.Abs(segment.bendingMultiplier),
                 Mathf.Abs(vAngle) - segment.maxAngleDifference
             ) * Mathf.Sign(vAngle) * Mathf.Sign(segment.bendingMultiplier);
             
             // Handle max bending angle here
             hAngle = Mathf.Clamp(hAngle, -segment.maxBendingAngle, segment.maxBendingAngle);
             vAngle = Mathf.Clamp(vAngle, -segment.maxBendingAngle, segment.maxBendingAngle);
             
             Vector3 referenceRightDir =
                 Vector3.Cross(segment.referenceUpDir, segment.referenceLookDir);
             
             // Lerp angles
             segment.angleH = Mathf.Lerp(
                 segment.angleH, hAngle, Time.deltaTime * segment.responsiveness
             );
             segment.angleV = Mathf.Lerp(
                 segment.angleV, vAngle, Time.deltaTime * segment.responsiveness
             );
             
             // Get direction
             lookDirGoal = Quaternion.AngleAxis(segment.angleH, segment.referenceUpDir)
                 * Quaternion.AngleAxis(segment.angleV, referenceRightDir)
                 * segment.referenceLookDir;
             
             // Make look and up perpendicular
             Vector3 upDirGoal = segment.referenceUpDir;
             Vector3.OrthoNormalize(ref lookDirGoal, ref upDirGoal);
             
             // Interpolated look and up directions in neck parent space
             Vector3 lookDir = lookDirGoal;
             segment.dirUp = Vector3.Slerp(segment.dirUp, upDirGoal, Time.deltaTime*5);
             Vector3.OrthoNormalize(ref lookDir, ref segment.dirUp);
             
             // Look rotation in world space
             Quaternion lookRot = (
                 (parentRot * Quaternion.LookRotation(lookDir, segment.dirUp))
                 * Quaternion.Inverse(
                     parentRot * Quaternion.LookRotation(
                         segment.referenceLookDir, segment.referenceUpDir
                     )
                 )
             );
             
             // Distribute rotation over all joints in segment
             Quaternion dividedRotation =
                 Quaternion.Slerp(Quaternion.identity, lookRot, effect / segment.chainLength);
             t = segment.lastTransform;
             for (int i=0; i<segment.chainLength; i++) {
                 t.rotation = dividedRotation * t.rotation;
                 t = t.parent;
             }
         }
         
         // Handle non affected joints
         for (int i=0; i<nonAffectedJoints.Length; i++) {
             Vector3 newJointDirection = Vector3.zero;
             
             foreach (Transform child in nonAffectedJoints[i].joint) {
                 newJointDirection = child.position - nonAffectedJoints[i].joint.position;
                 break;
             }
             
             Vector3 combinedJointDirection = Vector3.Slerp(
                 jointDirections[i], newJointDirection, nonAffectedJoints[i].effect
             );
             
             nonAffectedJoints[i].joint.rotation = Quaternion.FromToRotation(
                 newJointDirection, combinedJointDirection
             ) * nonAffectedJoints[i].joint.rotation;
         }
     
     
         if (Input.GetKey(KeyCode.UpArrow))
             offset += Time.deltaTime;
 
         if (Input.GetKey(KeyCode.DownArrow))
             offset -= Time.deltaTime;
 
         Ray cursorRay = Camera.main.ScreenPointToRay(Input.mousePosition);
         RaycastHit hit;
         if (Physics.Raycast(cursorRay, out hit)) 
         {
             MouseCursor = hit.point + offset * Vector3.down;
         }
 
         target = MouseCursor;
     }
     // The angle between dirA and dirB around axis
     public static float AngleAroundAxis (Vector3 dirA, Vector3 dirB, Vector3 axis) {
         // Project A and B onto the plane orthogonal target axis
         dirA = dirA - Vector3.Project(dirA, axis);
         dirB = dirB - Vector3.Project(dirB, axis);
         
         // Find (positive) angle between A and B
         float angle = Vector3.Angle(dirA, dirB);
         
         // Return angle multiplied with 1 or -1
         return angle * (Vector3.Dot(axis, Vector3.Cross(dirA, dirB)) < 0 ? -1 : 1);
     }
 }
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

60 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Lock rotation axis? 4 Answers

Incorrect script for slerp rotation 1 Answer

Look at multiple cameras 2 Answers

Suspension arm 1 Answer

Look at mouse? 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges