Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
2 captures
13 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
1
Question by SharonL75 · Aug 13, 2020 at 12:24 PM · c#rotatelookatclamplookrotation

How can I rotate my player head to face a target but only when the target is in the front of the player ?

The target is a cube in this case and the cube have a script attached that make the cube rotating around the player with random height :

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class RotateAround : MonoBehaviour
 {
     // Add this script to rotating object
     [Header("Gameobject that object/s will rotate around as center point")]
     public GameObject centerObj;//to get the position in worldspace to which this gameObject will rotate around.
 
     [Header("The axis by which it will rotate around")]
     public Vector3 axis;//by which axis it will rotate. x,y or z.
 
     [Header("Angle covered per update")]
     public float angle; //or the speed of rotation.
 
     public float upperLimit, lowerLimit, delay;// upperLimit & lowerLimit: heighest & lowest height; 
     private float height, prevHeight, time;//height:height it is trying to reach(randomly generated); prevHeight:stores last value of height;delay in radomness; 
 
     // Update is called once per frame
     void Update()
     {
         //Gets the position of your 'Center' and rotates this gameObject around it by the 'axis' provided at speed 'angle' in degrees per update 
         transform.RotateAround(centerObj.transform.position, axis, angle);
         time += Time.deltaTime;
         //Sets value of 'height' randomly within 'upperLimit' & 'lowerLimit' after delay 
         if (time > delay)
         {
             prevHeight = height;
             height = Random.Range(lowerLimit, upperLimit);
             time = 0;
         }
         //Mathf.Lerp changes height from 'prevHeight' to 'height' gradually (smooth transition)  
         transform.position = new Vector3(transform.position.x, Mathf.Lerp(prevHeight, height, time), transform.position.z);
     }
 }


Now the player head rig is rotating all the time since the player root object have Animator component. So I added a new child above the head rig empty GameObject and this is the object I'm rotating to look at the cube. This script is attached to the empty GameObject above the head rig.

I also dragged the head rih object to be child of the empty GameObject :

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class RotateToTarget : MonoBehaviour
 {
     public Transform target;
     public float speed = 1.0f;
 
     void Update()
     {
         // Determine which direction to rotate towards
         Vector3 targetDirection = target.position - transform.position;
 
         // The step size is equal to speed times frame time.
         float singleStep = speed * Time.deltaTime;
 
         // Rotate the forward vector towards the target direction by one step
         Vector3 newDirection = Vector3.RotateTowards(transform.forward, targetDirection, singleStep, 0.0f);
 
         // Calculate a rotation a step closer to the target and applies rotation to this object
         transform.rotation = Quaternion.LookRotation(newDirection);
     }
 }
 

The problem is when the cube is behind the player then the player head is rotating backward and I want that the head will look at the target cube smooth only when the cube enter the front view of the player. I'm trying to make the most realistic like human view when looking at something.

I tried to use Animator IK with SetWeight and SetPosition and it worked fine but I could not finding any way to change the SetWeight value from 1 to 0 slowly smooth. So I'm trying to do it on my own from scracth.

Another problem is seems to be that the player head is not rotating fast enough like the cube does move so sometimes the player head is not looking at the cube since he is rotating slower then the cube.

The main goal is to make the player head to look at the cube smooth only when the cube is in the front of the player.

Screenshot :

The player with settings

Here is a link for a short video clip I recorded showing the problem when the cube is behind the player and that the player head rotation speed is not the same speed as the cube so in most of the time the player is not looking at the cube but looking at it in general direction :

https://www.youtube.com/watch?v=gApXlKv7hKY&feature=youtu.be

00030.jpg (343.2 kB)
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
1

Answer by CardboardComputers · Aug 13, 2020 at 12:44 PM

You can use Vector3.Angle to get the angle difference between the player object's transform.forward vector and the direction to the cube, i.e. target.position - transform.position:

 float targetAngleFromForward = Vector3.Angle(transform.forward,
         target.position - transform.position);

Then, you can check this against some limiting condition, so that you only run the tracking code when it's within a certain angle of the player's forward direction.

Furthermore, if you want to use IK weights, you can lerp or smooth lerp the weight between 0 and 1. If you prefer to use vectors, you can also use their vector analogues. These methods have the added benefit of not being limited to a specific speed; instead, each will always take the same amount of time for the character to go from "not looking at the block" to "looking at the block". In other words, if the block moves very quickly, the character's head will turn faster in order to face it in the given time. If the block moves very slowly, the character's head will turn slower to accomodate.

Comment
Add comment · Show 10 · 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
avatar image SharonL75 · Aug 13, 2020 at 02:12 PM 1
Share

Can you show me please how to make the IK weights lerp/smooth lerp ? I tried it a lot without a success.

I tried this script on my player root object :

 using UnityEngine;
 using System;
 using System.Collections;
 using UnityEngine.SocialPlatforms;
 using UnityEditor.Animations;
 
 [RequireComponent(typeof(Animator))]
 
 public class IKControl : $$anonymous$$onoBehaviour
 {
     protected Animator animator;
 
     public bool ikActive = false;
     public Transform headObj = null;
     public Transform lookObj = null;
 
     private bool changeWeight = false;
 
     void Start()
     {
         animator = GetComponent<Animator>();
     }
 
     //a callback for calculating IK
     void OnAnimatorIK()
     {
         if (animator)
         {
             changeWeight = false;
 
             //if the IK is active, set the position and rotation directly to the goal. 
             if (ikActive)
             {
                 //changeWeight = false;
 
                 // Set the look target position, if one has been assigned
                 if (lookObj != null)
                 {
                     //animator.SetLookAtWeight(1, 1, 1, 1, 1);
                     animator.SetLookAtPosition(lookObj.position);
                 }
             }
 
             //if the IK is not active, set the position and rotation of the hand and head back to the original position
             else
             {              
                     changeWeight = true;              
             }
         }
     }
 
     private void FixedUpdate()
     {
         if(changeWeight == true)
         {
             Quaternion from = headObj.rotation;
             /**/
             Vector3 dir = headObj.position - lookObj.position;
             /**/
             float angle = $$anonymous$$athf.Atan2(dir.y, dir.x) * $$anonymous$$athf.Rad2Deg;
             Quaternion to = Quaternion.AngleAxis(angle, Vector3.forward);
             headObj.rotation = Quaternion.Slerp(from, to, 1f);
         }
     }
 }

but I found that even without the else part just if I tick the flag ikActive enabled false/true it's changing the player head weight between 1 and 0.

The else part and the code in the Update has no effect/ not working at all.

Can you please show me how to do it ? I want for example to make that when the flag ikActive is change to false when the game is running to slowly rotate the head slowly smooth back to to the original rotation/position using the weight.

avatar image CardboardComputers SharonL75 · Aug 13, 2020 at 03:03 PM 0
Share

Ah, my bad; the third parameter in the lerp functions are actually the interpolation ratio, not the time; in other words, they specify how far into the lerp you are. Based on your code, you'll want something like:

 private const float LERP_TI$$anonymous$$E = 1f;
 private float currentLerpTime;
 private void Update() {
     if (changeWeight) {
         currentLerpTime += Time.deltaTime;
         float lerpProgress = currentLerpTime / LERP_TI$$anonymous$$E;
         SomeKindOfLerp(startDirection, targetDirection, $$anonymous$$athf.Clamp01(lerpProgress));
     }
 }

where currentLerpTime is reset to 0 each time you want to lerp somewhere. Here, startDirection might be some stored value from the start of the lerp, or it might describe where you're facing at the current frame. These two choices will have slightly different behaviours, but I think they should both work; the former will follow the Slerp curve whereas the latter will follow some kind of an exponential curve. Notice that I put it in Update instead of FixedUpdate; I think that'll look prettier, since Update calls per frame whereas FixedUpdate calls per physics loop.

It's not very elegant and kind of messy, I know. Depending on what you want, you can also try SmoothDamp; it follows a different curve from Slerp and is implemented differently. Unity has a built in version for $$anonymous$$athf and Vector3, and someone made one for Quaternion. Like the Slerp example above, it also requires you to keep a reference variable across different calls.

Apologies again!

avatar image SharonL75 CardboardComputers · Aug 13, 2020 at 04:38 PM 0
Share

I tried it like this :

 using UnityEngine;
 using System;
 using System.Collections;
 using UnityEngine.SocialPlatforms;
 using UnityEditor.Animations;
 
 [RequireComponent(typeof(Animator))]
 
 public class IKControl : $$anonymous$$onoBehaviour
 {
     protected Animator animator;
 
     public bool ikActive = false;
     public Transform headObj = null;
     public Transform lookObj = null;
 
     private bool changeWeight = false;
     private const float LERP_TI$$anonymous$$E = 1f;
     private float currentLerpTime;
 
     void Start()
     {
         animator = GetComponent<Animator>();
     }
 
     //a callback for calculating IK
     void OnAnimatorIK()
     {
         if (animator)
         {
             changeWeight = false;
 
             //if the IK is active, set the position and rotation directly to the goal. 
             if (ikActive)
             {
                 //changeWeight = false;
 
                 // Set the look target position, if one has been assigned
                 if (lookObj != null)
                 {
                     animator.SetLookAtWeight(1, 1, 1, 1, 1);
                     animator.SetLookAtPosition(lookObj.position);
                 }
             }
 
             //if the IK is not active, set the position and rotation of the hand and head back to the original position
             else
             {              
                     changeWeight = true;              
             }
         }
     }
 
     private void Update()
     {
         if (changeWeight)
         {
             currentLerpTime += Time.deltaTime;
             float lerpProgress = currentLerpTime / LERP_TI$$anonymous$$E;
             Quaternion.Lerp(headObj.rotation, Quaternion.Euler(new Vector3(0,0,0)), $$anonymous$$athf.Clamp01(lerpProgress));
         }
     }
 }
 
 
 // Rotation head : X between 60 and -60
 // Rotation head : Y between 100 and -100
 // Rotation head : Z between 60 and -60 ( Only if needed optional )
 

But it's not working yet. Have you ever tried using the IK weight with lerp ? The problem is that no matter what you do when you set the flag ikActive to false it's changing the player head back to forward to the default rotation automatic and do it too fast.

The code in the Update never have a chance to execute. Once you uncheck the ikActive make it false it's changing the head rotation the weight to 0 so the code in the Update has no affect.

Even if I'm not setting the flag changeWeight to true and only set the flag ikActive to false it will change the head weight to 0.

I;m not sure if it's possible to lerp the weight or to wait before it will change it to 0 and make the code in the Update to affect

Show more comments

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

750 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 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 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 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 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 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 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 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 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 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 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 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 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

LookAt doesnt work with cardboard SDK or any camera movement 0 Answers

Rotating while rotating? 1 Answer

Align transform Y axis to -Physics.gravity 1 Answer

Clamping LookRotation angle 2 Answers

slow look at question 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