0
\$\begingroup\$

I have a 3rd person camera which can rotate around the player.

When I look at the back of the player and press forward, player goes forward. Then I rotate 360 around the player and "forward direction" is tilted for 90 degrees. So every 360 turn there is 90 degrees of direction change.

For example when camera is facing the right side of the player, when I press button to move forward, I want player to turn to the left and make that the "new forward".

I have Player object with Camera as child object. Camera object has Camera script. Inside Camera script there are Player and Camera classes. Player object itself, has Input Controller.

Also I'm making this script for joystick/ controller primarily.

My camera script so far:

using UnityEngine;
using System.Collections;

public class CameraScript : MonoBehaviour
{
    public GameObject Target;
    public float RotateSpeed = 10,
    FollowDistance = 20,
    FollowHeight = 10;
    float RotateSpeedPerTime,
    DesiredRotationAngle,
    DesiredHeight,
    CurrentRotationAngle,
    CurrentHeight,
    Yaw,
    Pitch;
    Quaternion CurrentRotation;

    void LateUpdate()
    {
        RotateSpeedPerTime = RotateSpeed * Time.deltaTime;

        DesiredRotationAngle = Target.transform.eulerAngles.y;
        DesiredHeight = Target.transform.position.y + FollowHeight;
        CurrentRotationAngle = transform.eulerAngles.y;
        CurrentHeight = transform.position.y;

        CurrentRotationAngle = Mathf.LerpAngle(CurrentRotationAngle, DesiredRotationAngle, 0);
        CurrentHeight = Mathf.Lerp(CurrentHeight, DesiredHeight, 0);

        CurrentRotation = Quaternion.Euler(0, CurrentRotationAngle, 0);
        transform.position = Target.transform.position;
        transform.position -= CurrentRotation * Vector3.forward * FollowDistance;
        transform.position = new Vector3(transform.position.x, CurrentHeight, transform.position.z);

        Yaw = Input.GetAxis("Right Horizontal") * RotateSpeedPerTime;
        Pitch = Input.GetAxis("Right Vertical") * RotateSpeedPerTime;
        transform.Translate(new Vector3(Yaw, -Pitch, 0));
        transform.position = new Vector3(transform.position.x, transform.position.y, transform.position.z);

        transform.LookAt(Target.transform);
    }
}

My player script:

using UnityEngine;
using System.Collections;

public class PlayerScript : MonoBehaviour
{
    public float RotateSpeed = 10,
    MoveSpeed = 10;
    float DeltaTime;
    public Transform cameraTransform;

    void Update()
    {
        DeltaTime = Time.deltaTime;
        transform.Rotate(0, Input.GetAxis("Right Horizontal") * RotateSpeed * DeltaTime, 0);
    }
}
\$\endgroup\$
2
  • \$\begingroup\$ No. I got a new problem. If I asked to resolve multiple problems in one question people would then tell me to make separate questions. You people are never satisfied. Also this is more specific. \$\endgroup\$ Aug 26, 2014 at 18:25
  • 1
    \$\begingroup\$ sure looks like a dupe to me, especially considering there's no actual question being asked here, just a description of the same situation \$\endgroup\$
    – jhocking
    Feb 23, 2015 at 0:09

2 Answers 2

0
\$\begingroup\$

If the player is looking directly at the camera we can use the following idea to find the direction the player should walk, based on the position of the camera.

We have two vectors C: (camera.Transform.Forward) the direction the camera is looking at and P (player.Transform.Forward) the direction the player is looking at.

By computing the acos of the dot product of these two vectors we can compute the angle between these to vectors.

angle = acos(dot(C, P);

This angle can be used to rate the player so that it faces the camera (just rotate the player by -angle) and it can be used to transform controller inputs so that no matter where the camera and player is 'left' will always be left as seen from the camera.

This can be done by constructing the left, forward, right, and backward vectors like this.

// Assumes the forward vector normally is (0, 0, 1) or
// (cos(pi/2 + 0), 0, sin(pi/2 + 0))   
vector3 forward = (cos(pi/2) + angle), 0, sin(pi /2 + angle);

If you wish the player to face the forward vector, or another vector you can again compute the acos of the dot product between that vector and the vector that points to where the player is currently facing. Just rotate the player by minus the result of that computation.

There might be small math errors in this answer (offsets wrong by half a pi, a minus that should or shouldn't be there) but I hope the general idea is now quite clear and that you can deduce the other direction vectors yourself.

\$\endgroup\$
6
  • \$\begingroup\$ sorry...but I've got more than few errors. Will you be kind and tell me where to place this code of yours. \$\endgroup\$ Aug 26, 2014 at 21:05
  • \$\begingroup\$ You should implement this pseudo code wherever you want to turn the player towards the direction you're pressing on the controller, as seen from the camera. Note that this is pseudo code. Acos should be replaced by the Unity/C# equivalent which I believe is Math.Acos() etc... Try to understand the math behind this, if anything is unclear, please do ask. \$\endgroup\$
    – Roy T.
    Aug 27, 2014 at 7:32
  • \$\begingroup\$ Hey. I found out that if I rotate camera, player rotates, which gave me idea. It wouldn't be the same thing as I asked help for, but it'll do. The script already did this but I just now realized that. Now how do I rotate them both simultaneously on purpose? Because those two are not rotated at the same speed neither the same side. \$\endgroup\$ Aug 27, 2014 at 20:17
  • \$\begingroup\$ No matter how big the distance to the player if the camera rotates x-degrees around the player and you rotate the player x-degrees as well they should be rotating at the same rotational speed (e.g. the player should always keep looking in the same relative direction as seen from the camera). \$\endgroup\$
    – Roy T.
    Aug 28, 2014 at 8:36
  • \$\begingroup\$ 1. Something funny is happening. You see that RotateSpeed? It's both in Player and Camera class. Regardless where I change that speed, it changes in both classes. And it's not the same speed nor side. Even when I changed the name to like PlayerRotateSpeed and CameraRotateSpeed it still changed both speeds. Because of this I set Camera speed to 2.5 (not 10) and Player speed to 65. Now is yaw extremely slow affected by Camera speed and pitch is affected by both Camera and Player speed. As for the side of Player rotation I wrote in Player script -RotateSpeed which did the job -->character limit \$\endgroup\$ Aug 28, 2014 at 8:50
-1
\$\begingroup\$

I shall rephrase, the direction the player is facing is the forward direction, Therefor the camera should face forward (i.e the direction the player is facing), so the camera should be aimed at the player location always (unless you choose it to follow a different object like a vehicle) so there fore the camera facing point is player.location (This isn't code just variables for vectors)

     Camera.facing =player.facing; /*this makes the camera face the way the player is facing...therefor camera will always face forward,( i.e the direction the player is facing...)rotating the player 360 degrees should place the camera back where it started (behind the player facing the way the player is facing) rotating it 180 degrees should place the camera still behind the player but but moved on the yaw to face the same way the player is now facing,the idea is not to make a whole new purpose of a "new forward" variable but use a variable that's already there....*/

     Camera.facing=player.location; //*his makes the camera face the location of your player which means the camera might not be facing where the player is facing but more at where he is, this method will allow you too see the front of the player if he is facing the camera, and the back if he is not,or his sides if he is moving that way (this method sounds like the one you need ;) ) */
     Camera.location=player.location.z-4&&player.location.y+2; /*this simply places the camera behind the player at all times (you can change this if you want...)

It also sounds like you don't understand this "player.location.x" (this is a vector player.location.x refers to the x piece of the vector where as player.location.y refers to the y piece of the vector and player.location.z refers to the z piece of the vector.... Understanding that should allow you to properly place the camera and view angle correctly, but I do want you to know that rotating 360 degrees should place the camera in the exact place it was... Feel free to ask more questions to me if you don't understand :) Hope this Helps :) Good Luck :)

\$\endgroup\$
7
  • \$\begingroup\$ I'm not good in c# so I don't know how would I implement that "+90 degrees". Could you be kind and add a sample or code for it? Thanks \$\endgroup\$ Aug 26, 2014 at 14:23
  • \$\begingroup\$ Well the idea is to make the camera move 90 degrees in that direction, but I don't see your camera location values... Do you have a camera class that you can show? \$\endgroup\$ Aug 26, 2014 at 17:07
  • \$\begingroup\$ That is camera class. But I also have Player class. I'll edit my question with that code. \$\endgroup\$ Aug 26, 2014 at 18:28
  • \$\begingroup\$ I don't think this answer makes much sense. In your example code you do not make any computation to find the relative direction between the camera and the player. \$\endgroup\$
    – Roy T.
    Aug 26, 2014 at 20:38
  • \$\begingroup\$ Relative Direction? The camera facing point is the location of the player \$\endgroup\$ Aug 26, 2014 at 20:51

Not the answer you're looking for? Browse other questions tagged .