Player Movement using joystick based on camera facing

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP


Player Movement using joystick based on camera facing



I develop Offline FPS Multiplayer Game.



When the Player Rotation value (0,0,0) then Player Move perfectly in Direction. but my problem is when i rotate the camera using touch input then player can also rotate his face and press to joystick button for move the player then player can not move the direction of camera facing.



My Joystick Script For Player


public class VirtualJoystick : MonoBehaviour, IDragHandler, IPointerUpHandler,IPointerDownHandler {


private Image bgImg;
private Image JoyStickImage;
private Vector3 InputVector;

private void Start(){
bgImg = GetComponent<Image> ();
JoyStickImage = transform.GetChild (0).GetComponent<Image> ();

}

public virtual void OnDrag(PointerEventData ped){
Vector2 pos;
if (RectTransformUtility.ScreenPointToLocalPointInRectangle (bgImg.rectTransform, ped.position, ped.pressEventCamera, out pos)) {
pos.x = (pos.x / bgImg.rectTransform.sizeDelta.x);
pos.y = (pos.y / bgImg.rectTransform.sizeDelta.y);

InputVector = new Vector3 (pos.x * 2 + 1, 0, pos.y * 2 - 1);
InputVector = (InputVector.magnitude > 1) ? InputVector.normalized : InputVector;

JoyStickImage.rectTransform.anchoredPosition = new Vector3 (InputVector.x * (bgImg.rectTransform.sizeDelta.x / 2.5f),
InputVector.z * (bgImg.rectTransform.sizeDelta.y / 2.5f));


}
}

public virtual void OnPointerDown(PointerEventData ped){

OnDrag (ped);
}

public virtual void OnPointerUp(PointerEventData ped){

InputVector = Vector3.zero;
JoyStickImage.rectTransform.anchoredPosition = Vector3.zero;
}

public float Horizontal(){

if (InputVector.x != 0) {
return InputVector.x;
} else {

return Input.GetAxis ("Horizontal");
}

}
public float Vertical(){

if (InputVector.z != 0)
return InputVector.z;
else
return Input.GetAxis ("Vertical");

}}



My Camera Rotation Script Using Input Touch


public class SwipeCam : MonoBehaviour {

private Vector3 firstPoint;
private Vector3 secondPoint;
private float xAngle = 0.0f;
private float yAngle = 0.0f;
private float xAngleTemp = 0.0f;
private float yAngleTemp = 0.0f;





void Start(){
xAngle = 0.0f;
yAngle = 0.0f;
this.transform.rotation = Quaternion.Euler (yAngle, xAngle, 0.0f);

}

void Update(){


if (Input.touchCount > 0) {

for (int i = 0; i < Input.touchCount; i++) {

Touch touch = Input.GetTouch (i);

if (touch.position.x > Screen.width / 2) {

if (touch.phase == TouchPhase.Began) {

firstPoint = Input.GetTouch (0).position;
xAngleTemp = xAngle;
yAngleTemp = yAngle;
}
if (touch.phase == TouchPhase.Moved) {
secondPoint = Input.GetTouch (0).position;

xAngle = xAngleTemp + (secondPoint.x - firstPoint.x) * 180.0f / Screen.width;
yAngle = yAngleTemp + (secondPoint.y - firstPoint.y) * 180.0f / -Screen.height;

yAngle = Mathf.Clamp (yAngle, -30f, 30f);


this.transform.rotation = Quaternion.Euler (yAngle, xAngle, 0.0f);
this.gameObject.GetComponentInParent<FPScontroller> ().transform.rotation = Quaternion.Euler (0.0f, xAngle, 0.0f);
//this.gameObject.GetComponentInParent<FPScontroller> ().transform.rotation = Quaternion.LookRotation(Vector3.forward,Vector3.up);


}

}
}
}


}}



Where should i change my code to facing the camera direction to player i don't understand, anyone can know then help me what should i change or add in this script. Thanks in advance.



That is my Player Script (FPSController.cs)


public class FPScontroller : MonoBehaviour {

// Should this script respond to input?
public bool canControl = true;
public GameObject lookObj; //This is root object that containc MainCamera, Weapons etc.
public GameObject joystick;
bool useFixedUpdate = false;


//Check when run, walk or when can run or not
[HideInInspector]
public bool Running ;
[HideInInspector]
public bool Walking;
[HideInInspector]
public bool canRun;
[HideInInspector]
public Vector3 rorationDir;

//Ladder variables
private GameObject mainCamera = null;
[HideInInspector]
public bool onLadder = false;
//private float ladderHopSpeed = 6.0f;

// For the next variables, @System.NonSerialized tells Unity to not serialize the variable or show it in the inspector view.
// Very handy for organization!

// The current global direction we want the character to move in.
[System.NonSerialized]
public Vector3 inputMoveDirection = Vector3.zero;

// Is the jump button held down? We use this interface instead of checking
// for the jump button directly so this script can also be used by AIs.
[System.NonSerialized]
public bool inputJump = false;

[HideInInspector]
public bool inputRun = false;

[HideInInspector]
public bool inputCrouch = false;

[HideInInspector]
public bool inputProne = false;

[System.Serializable]
public class FPScontrollerMovement {
// The maximum horizontal speed when moving
[HideInInspector]
public float maxForwardSpeed = 10.0f;
[HideInInspector]
public float maxSidewaysSpeed = 10.0f;
[HideInInspector]
public float maxBackwardsSpeed = 10.0f;

//Run and walk variables
public float WalkSpeed = 6.0f;
public float RunSpeed = 9.0f;
//Crouch
public bool canCrouch = true;
public float CrouchSpeed = 3.0f;
public float crouchHeight = 1.5f;
public float crouchSmooth = 8;
//prone
public bool canProne = true;
public float ProneSpeed = 1.5f;
public float proneHeight = 0.7f;



// Curve for multiplying speed based on slope (negative = downwards)
public AnimationCurve slopeSpeedMultiplier = new AnimationCurve(new Keyframe(-90, 1), new Keyframe(0, 1), new Keyframe(90, 0));

// How fast does the character change speeds? Higher is faster.
public float maxGroundAcceleration = 30.0f;
public float maxAirAcceleration = 20.0f;

// The gravity for the character
public float gravity = 10.0f;
public float maxFallSpeed = 20.0f;

[HideInInspector]
public bool enableGravity = true;

// For the next variables, @System.NonSerialized tells Unity to not serialize the variable or show it in the inspector view.
// Very handy for organization!

// The last collision flags returned from controller.Move
[System.NonSerialized]
public CollisionFlags collisionFlags;

// We will keep track of the character's current velocity,
[System.NonSerialized]
public Vector3 velocity;

// This keeps track of our current velocity while we're not grounded
[System.NonSerialized]
public Vector3 frameVelocity = Vector3.zero;

[System.NonSerialized]
public Vector3 hitPoint = Vector3.zero;

[System.NonSerialized]
public Vector3 lastHitPoint = new Vector3(Mathf.Infinity, 0, 0);
}
public FPScontrollerMovement movement = new FPScontrollerMovement();

void Awake () {
if (GetComponent<NetworkView> ().isMine) {

joystick = GameObject.Find ("Joystick");
controller = gameObject.GetComponent<CharacterController>();
standartHeight = controller.height;
/*if(GameObject.FindWithTag("LookObject") != null){
lookObj = GameObject.FindWithTag("LookObject");
}*/
centerY = controller.center.y;
tr = transform;

canRun = true;
canStand = true;
StartCoroutine(setupBools());

}
}

void Update () {
if (GetComponent<NetworkView> ().isMine) {
if (!useFixedUpdate) {
UpdateFunction ();
}

movement.velocity.x = joystick.GetComponent<VirtualJoystick> ().Horizontal () * 5f;
movement.velocity.z = joystick.GetComponent<VirtualJoystick> ().Vertical () * 5f;



//Run input
if (Input.GetAxis ("Vertical") > 0.1f && inputRun && canRun && !onLadder && Walking) {
if (canStand && canStandCrouch) {
OnRunning ();
}
} else {
OffRunning ();
}

//Check when walk or not
if ((movement.velocity.x > 0.01f || movement.velocity.z > 0.01f) || (movement.velocity.x < -0.01f || movement.velocity.z < -0.01f)) {
RunAnimation1 ();
Debug.Log ("Forward");
Walking = true;
}else if (movement.velocity.x > 0.01f) {
Walking = true;
Debug.Log ("Right");
} else if (movement.velocity.x < -0.01f) {
Walking = true;
Debug.Log ("Left");
} else {
RunAnimation ();
Walking = false;
}


if (!canControl)
return;

if (movement.canCrouch) {
if (!onLadder) {
Crouch ();
}
}

if (movement.canProne) {
if (!onLadder) {
Prone ();
}
}

if (onLadder) {
grounded = false;
crouch = false;
prone = false;
}

if (!crouch && !prone && controller.height < standartHeight - 0.01f) {
controller.height = Mathf.Lerp (controller.height, standartHeight, Time.deltaTime / movement.crouchSmooth);
controller.center = new Vector3 (controller.center.x, Mathf.Lerp (controller.center.y, centerY, Time.deltaTime / movement.crouchSmooth), controller.center.z);
lookObj.transform.localPosition = new Vector3 (lookObj.transform.localPosition.x, Mathf.Lerp (lookObj.transform.localPosition.y, standartHeight, Time.deltaTime / movement.crouchSmooth), lookObj.transform.localPosition.z);
}
}
}

void RunAnimation(){
GetComponent<NetworkView> ().RPC ("SysnAnimation", RPCMode.All, 0);
}
void RunAnimation1(){
GetComponent<NetworkView> ().RPC ("SysnAnimation", RPCMode.All, 1);
}
void RunAnimation2(){
GetComponent<NetworkView> ().RPC ("SysnAnimation", RPCMode.All, 2);
}

[RPC]
void SysnAnimation(int index){
if (index == 0) {
GetComponent<Animator> ().Play ("Idle Aim");
} else if (index == 1) {
GetComponent<Animator> ().Play ("Walk Aiming");
} else if (index == 2) {
GetComponent<Animator> ().Play ("Jump");
}
}

void OnRunning (){
Debug.Log ("Run");
Running = true;
movement.maxForwardSpeed = movement.RunSpeed;
movement.maxSidewaysSpeed = movement.RunSpeed;
//Make bigger extra height when player run to increase jump distance
jumping.extraHeight = jumping.baseHeight + 0.15f;
}

void OffRunning (){
Running = false;
if(crouch || prone)
return;
movement.maxForwardSpeed = movement.WalkSpeed;
movement.maxSidewaysSpeed = movement.WalkSpeed;
movement.maxBackwardsSpeed = movement.WalkSpeed/2;
//Change extraheight value to default when player walk
jumping.extraHeight = jumping.baseHeight;
}}




2 Answers
2



Your camera and joystick code looks fine, but that's not where the problem is.



I'll assume your player movement code looks something like this:



In code form, that might look something like this:


//returns the world-space direction that player wants to move
Vector3 GetDesiredMovement(float inputForward, float inputRight) {
//get a vector pointing to player's right
Vector3 dirRight = Camera.main.transform.right;
dirRight.y = 0f;
dirRight.Normalize();

//get a vector pointing to player's front
Vector3 dirForward = Camera.main.transform.forward;
dirForward.y = 0f;
dirForward.Normalize();

//calculate desired movement based on input
Vector3 desiredMovement = (dirForward * inputForward) + (dirRight * inputRight);
desiredMovement.Normalize();
return desiredMovement;
}



What if "right" and "forward" need to be relative to some other object in the scene, such as a camera? It's easier than you might think: just read those values directly from the camera's transform component.



You could do that by replacing just two lines from the above example:


Vector3 dirRight = Camera.main.transform.right;

Vector3 dirForward = Camera.main.transform.forward;





Thanks to answer but there is nothing like this type code in my player script.
– Darshan Soni
Feb 22 '17 at 11:50





@DarshanSoni Somewhere in your project, there must be some code that reads joystick input and causes player movement. That's the code that you will need to tweak.
– rutter
Feb 22 '17 at 17:26





Check my update i upload my player script and there is only in update function i reads joystick input for play player animation.
– Darshan Soni
Feb 24 '17 at 4:52





In my playerScript Update Function there is Two line that read the joystick input for player movement. movement.velocity.x = joystick.GetComponent<VirtualJoystick> ().Horizontal () * 5f; movement.velocity.z = joystick.GetComponent<VirtualJoystick> ().Vertical () * 5f; But That is not read the Rotation of player . what change to read the Player rotation with joystick input..Please Tell me what change i do.
– Darshan Soni
Feb 25 '17 at 7:14




movement.velocity.x = joystick.GetComponent<VirtualJoystick> ().Horizontal () * 5f; movement.velocity.z = joystick.GetComponent<VirtualJoystick> ().Vertical () * 5f;





@DarshanSoni Instead of directly assigning x and z components, it will be easier to compose a vector using the method I provided above.
– rutter
Feb 27 '17 at 19:22


x


z



I solved the problem of basing player movement of the camera's direction.



In my Player's script there are two lines that read joystick input:


movement.velocity.x = joystick.GetComponent<VirtualJoystick> ().Horizontal () * 5f;
movement.velocity.z = joystick.GetComponent<VirtualJoystick> ().Vertical () * 5f;`



I changed them to this:


Vector3 DirectionVector =
new Vector3 (joystick.GetComponent<VirtualJoystick> ().Horizontal (), 0f, joystick.GetComponent<VirtualJoystick> ().Vertical ());
movement.velocity = transform.rotation * DirectionVector * 10f;



Directly add joystick value in movement vector. I just multiply it to the joystick input vector and solve my problem.



Now the player moves based on the player rotation and where the camera is facing.
Thanks everyone for help.






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Makefile test if variable is not empty

Will Oldham

Visual Studio Code: How to configure includePath for better IntelliSense results