How can I use virtual joystick for control fps character controller? - c#

Here is my virtual joystick controller script. Now how can i use this for control fps character controller movement both forward and side?
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System.Collections;
public class JoyStickController : MonoBehaviour , IDragHandler, IPointerUpHandler ,IPointerDownHandler{
private Image bgImg;
private Image joyStickImg;
public Vector3 InputDirection{ set; get; }
// Use this for initialization
void Start () {
bgImg = GetComponent<Image> ();
joyStickImg = transform.GetChild (0).GetComponent<Image> ();
InputDirection = Vector3.zero;
}
public virtual void OnDrag(PointerEventData ped){
Vector2 pos = Vector2.zero;
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));
float x = (bgImg.rectTransform.pivot.x == 1) ? pos.x * 2 + 1 : pos.x * 2 - 1;
float y = (bgImg.rectTransform.pivot.y == 1) ? pos.y* 2 + 1 : pos.y * 2 - 1;
InputDirection = new Vector3 (x, 0, y);
InputDirection = (InputDirection.magnitude > 1) ? InputDirection.normalized : InputDirection;
joyStickImg.rectTransform.anchoredPosition = new Vector3 (InputDirection.x * (bgImg.rectTransform.sizeDelta.x / 3)
, InputDirection.z * (bgImg.rectTransform.sizeDelta.y / 3));
}
}
public virtual void OnPointerDown(PointerEventData ped){
OnDrag (ped);
}
public virtual void OnPointerUp(PointerEventData ped){
InputDirection = Vector3.zero;
joyStickImg.rectTransform.anchoredPosition = Vector3.zero;
Debug.Log("Unpress");
}
public float Horizontal()
{
if (InputDirection.x != 0)
return InputDirection.x;
else
return Input.GetAxis("Horizontal");
}
public float Vertical()
{
if (InputDirection.z != 0)
return InputDirection.z;
else
return Input.GetAxis("Vertical");
}
}
Here is my virtual joystick controller script. Now how can I use this for control fps character controller movement both forward and side?

FPS uses CharacterController. You move CharacterController with CharacterController.Move and the Move function take Vector3 as parameter.
All you have to do is pass in InputDirection from your Visual Joystick to the Move parameter.
float speed = 20;
CharacterController controller = GetComponent<CharacterController>();
controller.Move(InputDirection * speed * Time.deltaTime);
Or
Use the Horizontal() and Vertical() functions from your Visual Joystick.
public float speed = 6.0F;
public float jumpSpeed = 8.0F;
public float gravity = 20.0F;
private Vector3 moveDirection = Vector3.zero;
void Update() {
CharacterController controller = GetComponent<CharacterController>();
if (controller.isGrounded) {
moveDirection = new Vector3(Horizontal(), 0, Vertical());
moveDirection = transform.TransformDirection(moveDirection);
moveDirection *= speed;
if (Input.GetButton("Jump"))
moveDirection.y = jumpSpeed;
}
moveDirection.y -= gravity * Time.deltaTime;
controller.Move(moveDirection * Time.deltaTime);
}

Related

Cant change transform.position player on Unity

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class teleporttospawn : MonoBehaviour
{
public GameObject player; /// player
public Transform fps; /// also player
private void OnTriggerEnter(Collider other)
{
Debug.Log("teleport succes.");
fps.transform.position = new Vector3(-3.82f, 1.08f, -1.69f); // DONT WORK
player.transform.position = new Vector3(-3.82f, 1.08f, -1.69f); //DONT WORK
}
}
I have two players in the script above because I tried to move it in two ways but nothing worked
So I tried to set the object to vector3 and try to move the player to the object, so nothing comes out
I need teleport player when he triger the collider. Debug.Log work but transform.position dont work.
Its dosent work from this script -> fpscontroller
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class fpscontroller : MonoBehaviour
{
public float walkingSpeed = 7.5f;
public float runningSpeed = 11.5f;
public float jumpSpeed = 8.0f;
public float gravity = 20.0f;
public Camera playerCamera;
public float lookSpeed = 2.0f;
public float lookXLimit = 45.0f;
CharacterController characterController;
Vector3 moveDirection = Vector3.zero;
float rotationX = 0;
[HideInInspector]
public bool canMove = true;
public GameObject tp;
private void OnTriggerEnter(Collider collision)
{
if (collision.gameObject.CompareTag("tp"))
{
while(transform.position != tp.transform.position)
{
Debug.Log("teleport succes.");
gameObject.transform.position = tp.transform.position;
}
}
}
void Start()
{
transform.position = gameObject.transform.position;
characterController = GetComponent<CharacterController>();
// Lock cursor
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
}
void Update()
{
// We are grounded, so recalculate move direction based on axes
Vector3 forward = transform.TransformDirection(Vector3.forward);
Vector3 right = transform.TransformDirection(Vector3.right);
// Press Left Shift to run
bool isRunning = Input.GetKey(KeyCode.LeftShift);
float curSpeedX = canMove ? (isRunning ? runningSpeed : walkingSpeed) * Input.GetAxis("Vertical") : 0;
float curSpeedY = canMove ? (isRunning ? runningSpeed : walkingSpeed) * Input.GetAxis("Horizontal") : 0;
float movementDirectionY = moveDirection.y;
moveDirection = (forward * curSpeedX) + (right * curSpeedY);
if (Input.GetButton("Jump") && canMove && characterController.isGrounded)
{
moveDirection.y = jumpSpeed;
}
else
{
moveDirection.y = movementDirectionY;
}
// Apply gravity. Gravity is multiplied by deltaTime twice (once here, and once below
// when the moveDirection is multiplied by deltaTime). This is because gravity should be applied
// as an acceleration (ms^-2)
if (!characterController.isGrounded)
{
moveDirection.y -= gravity * Time.deltaTime;
}
// Move the controller
characterController.Move(moveDirection * Time.deltaTime);
// Player and Camera rotation
if (canMove)
{
rotationX += -Input.GetAxis("Mouse Y") * lookSpeed;
rotationX = Mathf.Clamp(rotationX, -lookXLimit, lookXLimit);
playerCamera.transform.localRotation = Quaternion.Euler(rotationX, 0, 0);
transform.rotation *= Quaternion.Euler(0, Input.GetAxis("Mouse X") * lookSpeed, 0);
}
}
}

Unity jump script delay

Im making a 3d game in unity, and so I made a cs script for movement of my charecter, walking and moveing the camera works fine, however when i added the jump function, it had a delay. You could press the jump button 5 times, with no result. Then you press it again, and it jumps. I cant figure out why this does this.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public CharacterController characterController;
public int speed = 6;
public float gravity = 9.87f;
private float verticalspeed = 0;
private Vector3 moveDirection = Vector3.zero;
public Transform Camera;
public float Sensitivity = 2f;
public float uplimit = -50;
public float downlimit = -50;
public float jumpspeed = 5.0f;
void Update()
{
move();
cameramove();
void cameramove()
{
float horizontal = Input.GetAxis("Mouse X");
float vertical = Input.GetAxis("Mouse Y");
transform.Rotate(0, horizontal * Sensitivity, 0);
Camera.Rotate(-vertical * Sensitivity, 0, 0);
Vector3 currentRotation = Camera.localEulerAngles;
if (currentRotation.x > 180) currentRotation.x -= 360;
currentRotation.x = Mathf.Clamp(currentRotation.x, uplimit, downlimit);
Camera.localRotation = Quaternion.Euler(currentRotation);
}
void move()
{
float horizontalMove = Input.GetAxis("Horizontal");
float verticalMove = Input.GetAxis("Vertical");
if (characterController.isGrounded) verticalspeed = 0;
else verticalspeed -= gravity * Time.deltaTime;
Vector3 gravityMove = new Vector3(0, verticalspeed, 0);
Vector3 move = transform.forward * verticalMove + transform.right * horizontalMove;
characterController.Move(speed * Time.deltaTime * move + gravityMove * Time.deltaTime);
if (characterController.isGrounded && Input.GetButton("Jump"))
{
moveDirection.y = jumpspeed;
}
moveDirection.y -= gravity * Time.deltaTime;
characterController.Move(moveDirection * Time.deltaTime);
}
}
}
Assuming your character has a RigidBody assigned to it, you can refer it on your script as,
public class PlayerMovement : MonoBehaviour
{
private Rigidbody myrigidbody;
void Start () {
myrigidbody = GetComponent<Rigidbody>();
}
}
Then you can pass the jumpspeed as a Vector3, and probably you might have to trigger your animation here as well.
if (characterController.isGrounded && Input.GetButton("Jump"))
{
characterController.isGrounded = false;
myrigidbody.AddForce(new Vector3(0, jumpspeed, 0));
// Trigger your animation, myanimator.SetTrigger("jump");
}
Unity character controller move documentation also contains jump function.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Example : MonoBehaviour
{
private CharacterController controller;
private Vector3 playerVelocity;
private bool groundedPlayer;
private float playerSpeed = 2.0f;
private float jumpHeight = 1.0f;
private float gravityValue = -9.81f;
private void Start()
{
controller = gameObject.AddComponent<CharacterController>();
}
void Update()
{
groundedPlayer = controller.isGrounded;
if (groundedPlayer && playerVelocity.y < 0)
{
playerVelocity.y = 0f;
}
Vector3 move = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
controller.Move(move * Time.deltaTime * playerSpeed);
if (move != Vector3.zero)
{
gameObject.transform.forward = move;
}
// Changes the height position of the player..
if (Input.GetButtonDown("Jump") && groundedPlayer)
{
playerVelocity.y += Mathf.Sqrt(jumpHeight * -3.0f * gravityValue);
}
playerVelocity.y += gravityValue * Time.deltaTime;
controller.Move(playerVelocity * Time.deltaTime);
}
}

Unity Character Controller animation problem

I just started my adventure with unity and I got stuck.
I need to make my character turn on animation walk when I press "W" and when there is no any key pressed stop and do Idle animation for being not moved (Sorry for my english I'm not a native speaker) and then when I press space char should jump and use jump anim my char actually move and jump but repeat only one animation even when I don't press any key.
Further, I want to make Climbing, Ledge Climb, character falling from the edge, etc smth like in Assassin's Creed. I want to animation play on keypress.I just start to figure it out using transition but still luck of results
I'm not sure what should I change, need a help.
using UnityEngine;
using System.Collections;
public class PlayerController2 : MonoBehaviour
{
public float walkSpeed = 20;
public float runSpeed = 40;
public float gravity = -80;
public float jumpHeight = 15;
[Range(0, 1)]
public float airControlPercent;
public float turnSmoothTime = 0.2f;
float turnSmoothVelocity;
public float speedSmoothTime = 0.1f;
float speedSmoothVelocity;
float currentSpeed;
float velocityY;
Animator animator;
Transform cameraT;
CharacterController controller;
void Start()
{
animator = GetComponent<Animator>();
cameraT = Camera.main.transform;
controller = GetComponent<CharacterController>();
}
void Update()
{
// input
Vector2 input = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));
Vector2 inputDir = input.normalized;
bool running = Input.GetKey(KeyCode.LeftShift);
Move(inputDir, running);
if (Input.GetKeyDown(KeyCode.Space))
{
Jump();
}
// animator
float animationSpeedPercent = ((running) ? currentSpeed / runSpeed : currentSpeed / walkSpeed * .5f);
animator.SetFloat("speedPercent", animationSpeedPercent, speedSmoothTime, Time.deltaTime);
}
void Move(Vector2 inputDir, bool running)
{
if (inputDir != Vector2.zero)
{
float targetRotation = Mathf.Atan2(inputDir.x, inputDir.y) * Mathf.Rad2Deg + cameraT.eulerAngles.y;
transform.eulerAngles = Vector3.up * Mathf.SmoothDampAngle(transform.eulerAngles.y, targetRotation, ref turnSmoothVelocity, GetModifiedSmoothTime(turnSmoothTime));
}
float targetSpeed = ((running) ? runSpeed : walkSpeed) * inputDir.magnitude;
currentSpeed = Mathf.SmoothDamp(currentSpeed, targetSpeed, ref speedSmoothVelocity, GetModifiedSmoothTime(speedSmoothTime));
velocityY += Time.deltaTime * gravity;
Vector3 velocity = transform.forward * currentSpeed + Vector3.up * velocityY;
controller.Move(velocity * Time.deltaTime);
currentSpeed = new Vector2(controller.velocity.x, controller.velocity.z).magnitude;
if (controller.isGrounded)
{
velocityY = 0;
}
}
void Jump()
{
if (controller.isGrounded)
{
float jumpVelocity = Mathf.Sqrt(-2 * gravity * jumpHeight);
velocityY = jumpVelocity;
}
}
float GetModifiedSmoothTime(float smoothTime)
{
if (controller.isGrounded)
{
return smoothTime;
}
if (airControlPercent == 0)
{
return float.MaxValue;
}
return smoothTime / airControlPercent;
}
}

Unity 2018 C# - Fbx Running animation scaling with Input?

I have figured out how to get fbx animations working in Unity for my character in my adventure game, but now I wish to have my character's running animation move with its speed of motion being in relation to the input of the control stick on an xbox controller.
In addition, when I add a walking animation in the future I wish to make a threshold for the control stick input so that the character walks when there is minimal input from the control stick and running when there is more input from the control stick. Any advice?
Here is my code.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerCharacterController : MonoBehaviour {
static Animator anim;
public bool walking;
public GameObject playerModel, Hero;
//Transforms
public Transform playerCam, character, centerPoint;
private Vector3 moveDirection;
//character controller declaration
CharacterController player;
//Mouse Rotation
private float rotX, rotY;
//Mouse Y Position
public float mouseYPosition = 1f;
//Mouse Sensitivity
public float Sensitivity = 10f;
//Mouse Zoom
private float zoom;
public float zoomSpeed = 2;
//Clamping Zoom
public float zoomMin = -2f;
public float zoomMax = -10f;
public float rotationSpeed = 5f;
//Move Front Back left & Right
private float moveFB, moveLR;
//Movement Speed
public float Speed = 2f;
//Velocity of Gravity
public float verticalVelocity;
//Jump Distance
public float jumpDist = 5f;
//Multiple Jumps
int jumpTimes;
//To use with Dialogue Manager
public DialogueManager DiagM;
public AudioClip jumpSound;
public AudioClip HurtSound;
AudioSource audioSource;
//knockback
public float knockBackForce;
public float knockBackTime;
private float knockBackCounter;
// Use this for initialization
void Start ()
{
//character controller
player = GameObject.Find("Player").GetComponent<CharacterController> ();
anim = GetComponent<Animator>();
//mouse zoom
zoom = -3;
centerPoint.transform.position = playerCam.transform.position;
centerPoint.transform.parent = null;
audioSource = GetComponent<AudioSource>();
}
// Update is called once per frame
void Update ()
{
//if (DiagM.StartDialogue)
//{ return; }
//Mouse Zoom Input
zoom += Input.GetAxis ("Mouse ScrollWheel") * zoomSpeed;
if (zoom > zoomMin)
zoom = zoomMin;
if (zoom < zoomMax)
zoom = zoomMax;
//Mouse Camera Input
playerCam.transform.localPosition = new Vector3 (0, 0, zoom);
//Mouse Rotation
rotX += Input.GetAxis ("Mouse X") * Sensitivity;
rotY -= Input.GetAxis ("Mouse Y") * Sensitivity;
//Clamp Camera
rotY = Mathf.Clamp (rotY, -60f, 60f);
playerCam.LookAt (centerPoint);
centerPoint.localRotation = Quaternion.Euler (rotY, rotX, 0);
//Movement Speed
if (knockBackCounter <= 0)
{
moveDirection = (transform.forward * Input.GetAxis("Vertical")) + (transform.right * Input.GetAxis("Horizontal"));
moveDirection = moveDirection * Speed;
moveDirection.y = verticalVelocity;
player.Move(moveDirection * Time.deltaTime);
//Movement Rotation
centerPoint.position = new Vector3 (character.position.x, character.position.y + mouseYPosition, character.position.z);
//knockback disable
//Movement Input
if (Input.GetAxis("Vertical") != 0 || Input.GetAxis("Horizontal") != 0)
{
transform.rotation = Quaternion.Euler(0f, centerPoint.rotation.eulerAngles.y, 0f);
Quaternion turnAngle = Quaternion.LookRotation(new Vector3(moveDirection.x, 0f, moveDirection.z));
playerModel.transform.rotation = Quaternion.Slerp(playerModel.transform.rotation, turnAngle, Time.deltaTime * rotationSpeed);
if (player.isGrounded == true)
{
anim.Play("Running");
}
}
else
{
if (player.isGrounded == true)
{ anim.Play("Idle"); }
}
if (player.isGrounded == true)
{
jumpTimes = 0;
verticalVelocity = -Physics.gravity.y * Time.deltaTime;
}
else
{
verticalVelocity += Physics.gravity.y * Time.deltaTime;
}
if (Input.GetButtonDown("Submit"))
{
anim.Play("Hello");
}
if (jumpTimes < 1)
{
if (Input.GetButtonDown("Jump"))
{
verticalVelocity += jumpDist;
anim.Play("Jump");
audioSource.PlayOneShot(jumpSound, 1F);
jumpTimes += 1;
}
}
}
else
{
knockBackCounter -= Time.deltaTime;
}
}
public void Knockback(Vector3 direction)
{
knockBackCounter = knockBackTime;
anim.SetTrigger("isJumping");
audioSource.PlayOneShot(HurtSound, 50F);
moveDirection = direction * knockBackForce;
moveDirection.y = knockBackForce;
}
}

Rotate GameObject based on key presses and based on Terrain slope/curvature

I have code in C# in a game in Unity that needs to rotate the player based on the slope of the terrain but the RotateTowards function(calculates the slope and angle) doesn't allow the object to be rotated sideway to move it in different directions. If I take out the rotateTowards function, rotations sideways work. If I dont, the correct slope rotation works but player won'r rotate sideways when buttons are pressed.
How could I fix this so the player could rotate in both ways?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController1 : MonoBehaviour
{
[System.Serializable]
public class MoveSettings
{
public float forwardVel = 10f; // walk speed
public float rotateVel = 100; // character rotation speed, character can walk 360 degree
public float jumpVel = 25f;
public LayerMask ground;
public Transform backLeft; // back left feet
public Transform backRight; // back right feet
public Transform frontLeft; // front left feet
public Transform frontRight; // front left feet
}
[System.Serializable]
public class PhysicsSettings
{
public float downAccel = 0.75f; // down speed when not grounded
}
public GameObject Model;
public GameObject Origin;
public MoveSettings moveSettings = new MoveSettings();
public PhysicsSettings physicsSettings = new PhysicsSettings();
private Vector3 velocity = Vector3.zero;
private Quaternion targetRotation;
private CharacterController cc;
private float forwardInput, turnInput, jumpInput = 0;
private RaycastHit lr;
private RaycastHit rr;
private RaycastHit lf;
private RaycastHit rf;
private Vector3 upDir;
private Animator Anim; // global private variable
private void Start()
{
Anim = GetComponent<Animator>(); // in the Start function
targetRotation = transform.rotation;
cc = GetComponent<CharacterController>();
}
public bool Grounded()
{
return cc.isGrounded;
}
private void FixedUpdate()
{
Run(); // calculate the velocity to be applied on character controller, stored in the velocity variable
Jump(); // code for jumping
GetInput(); // movement input keys
Turn(); // character movement direction input
cc.Move(transform.TransformDirection(velocity) * Time.deltaTime);
RotateTowardsGround();
}
private void GetInput()
{
Anim.SetFloat("vSpeed", forwardInput); // in the GetInput() function
Anim.SetFloat("Direction", 1f);
forwardInput = Input.GetAxis("Vertical");
turnInput = Input.GetAxis("Horizontal");
jumpInput = Input.GetAxisRaw("Jump");
}
private void Turn()
{
targetRotation *= Quaternion.AngleAxis(moveSettings.rotateVel * turnInput * Time.deltaTime, Vector3.up);
transform.rotation = targetRotation;
}
public void Jump()
{
if (jumpInput > 0 && Grounded())
{
velocity.y = moveSettings.jumpVel;
}
else if (jumpInput == 0 && Grounded())
{
velocity.y = 0;
}
else
{
velocity.y -= physicsSettings.downAccel;
}
}
private void Run()
{
velocity.z = moveSettings.forwardVel * forwardInput;
}
public void RotateTowardsGround()
{
// we have four feet
Physics.Raycast(moveSettings.backLeft.position + Vector3.up, Vector3.down, out lr);
Physics.Raycast(moveSettings.backRight.position + Vector3.up, Vector3.down, out rr);
Physics.Raycast(moveSettings.frontLeft.position + Vector3.up, Vector3.down, out lf);
Physics.Raycast(moveSettings.frontRight.position + Vector3.up, Vector3.down, out rf);
upDir = (Vector3.Cross(rr.point - Vector3.up, lr.point - Vector3.up) +
Vector3.Cross(lr.point - Vector3.up, lf.point - Vector3.up) +
Vector3.Cross(lf.point - Vector3.up, rf.point - Vector3.up) +
Vector3.Cross(rf.point - Vector3.up, rr.point - Vector3.up)
).normalized;
Debug.DrawRay(rr.point, Vector3.up);
Debug.DrawRay(lr.point, Vector3.up);
Debug.DrawRay(lf.point, Vector3.up);
Debug.DrawRay(rf.point, Vector3.up);
Model.transform.up = upDir;
}
}
The proper way to rotate object based on Terrain slope/curvature is to first throw raycast then obtain the returned RaycastHit.normal value and assign it your to the object's transform.up. It's better to use Lerp or Slerp to do this form smooth ration.
As for the position of the object, you can calculate that with Terrain.activeTerrain.SampleHeight as described in this post or you can use RaycastHit.point like you did in the code from your question.
Below is an example of what I described above. It is a minimal code to move/rotate object over a terrain. You can modify it to fit your four character legs scenario.
public class Hover : MonoBehaviour
{
public Transform objectToMove;
public float maxSpeed = 10f;
public float angleSpeed = 5f;
public float groundDistOffset = 2f;
private Vector3 toUpPos = Vector3.zero;
void Update()
{
float hInput = Input.GetAxis("Horizontal");
float vInput = Input.GetAxis("Vertical");
Vector3 objPos = objectToMove.position;
objPos += objectToMove.forward * vInput * maxSpeed * Time.deltaTime;
objPos += objectToMove.right * hInput * maxSpeed * Time.deltaTime;
RaycastHit hit;
if (Physics.Raycast(objectToMove.position, -Vector3.up, out hit))
{
//Get y position
objPos.y = (hit.point + Vector3.up * groundDistOffset).y;
//Get rotation
toUpPos = hit.normal;
}
//Assign position of the Object
objectToMove.position = objPos;
//Assign rotation/axis of the Object
objectToMove.up = Vector3.Slerp(objectToMove.up, toUpPos, angleSpeed * Time.deltaTime);
}
}

Categories

Resources