# Unity - Make a Mirror character of player in movement

What I want to achieve is :

• I have a 3D game - with player in third person - and using cinemachine Camera - imagine it like PUBG where you can look any where - the direction of the player does not change until the player is moving - the direction of character change in the same direction as camera

• I want to make some sort of Shadow character as enemy , it will face the player - and mimic every movement exactly - not harmful

• so when the player move forward - the other copy also move toward player - thus blocking his movement

so I want to achieve this using RigidBody - as Physics is needed to solve this puzzle

I tried different approaches- until I got to this code - it works OK - until I change the camera direction and then every thing is not working any more

     public Transform cam ;

float speed = 10f;    //How fast the player can move
float turnSpeed = 100;    //How fast the player can rotate

public Animator animator; //Animation Control
Rigidbody rigidBody; //Make sure you have a rigidbody

void Start()
{
//Initialize appropriate components
animator = GetComponent<Animator> ();
rigidBody = GetComponent<Rigidbody>();
cam = Camera.main.transform;
}

//No need for update function right now, physics work better in Fixed Update

void FixedUpdate()
{
//right is shorthand for (1,0,0) or the x value            forward is short for (0,0,1) or the z value
Vector3 dir =  (-cam.forward * Input.GetAxis("Vertical"))+ (cam.right * Input.GetAxis("Horizontal")) ;

dir.y = 0;//Keeps character upright against slight fluctuations

if (Input.GetAxis("Horizontal") != 0 ||Input.GetAxis("Vertical") != 0)
{
//rotate from this /........to this............../.........at this speed
rigidBody.rotation = Quaternion.Slerp (transform.rotation, Quaternion.LookRotation (dir), turnSpeed * Time.deltaTime);
rigidBody.velocity = transform.forward * speed;
animator.SetFloat ("Blend", 10);//Walk or run Blend works well here
} else
{
rigidBody.velocity = new Vector3(0,0,0).normalized;
animator.SetFloat ("Blend", 0);//Idle Blend works well here
}
}

}


Use Vector3.Reflect(...) function to get a movement vector for the enemy that is a reflection of the player's movement vector.
First argument of the function is your player movement vector, in your case it should be rigidBody.velocity.
The second argument is a vector that represents the normal of the plane from which the player's vector will be reflected. You'll need to decide what will be the 'mirror' plane for the reflection and use a vector that points out from the mirror plane.
I think you could use a direction vector that points from the enemy to the player as the mirror normal vector, so the enemy's movements won't depend on neither the camera direction nor the direction the player's model is looking at.
So, something like this:

Vector3 dirToPlayer = player.position - enemy.position;
dirToPlayer.Normalize(); // the normal vector should have magnitude 1 so the distance between the enemy and the player won't affect the reflection results.
Vector3 reflectedVector = Vector3.Reflect(playerRigidBody.velocity, dirToPlayer);
enemyRigidBody.velocity = reflectedVector;

• Awesome, exactly what I needed, Your code works amazing , the only problem is that if I used your calculation to detect the direction to Player , this makes the enemy always return to meet the player even though he might be not Aligned anymore- I guess this is because I didn't explain the purpose fully of this script - so this is perfect if you want to make mirror like area , but for my need as puzzle I changed the dirToPlay with vector3 represent the plane I need. also this code doesn't make the enemy change the rotation , but it is way much hilarious like this and i really love it ,Thank you Apr 29, 2021 at 22:32
• the Code I used if any one need it : Vector3 reflectedVector = Vector3.Reflect(PlayerRigid.velocity, new Vector3(1,0,0)); rigidBody.velocity = reflectedVector; if(rigidBody.velocity.magnitude > 0){ animator.SetFloat ("Blend", 10);//Walk or run Blend works well here }else{ animator.SetFloat ("Blend", 0);//Idle Blend works well here } Apr 29, 2021 at 22:35