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 :

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 :

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.