CharacterController.Move Jumping Issue - c#

I have been using CharacterController.Move to control my fps character.
I have ran into a problem where my character does small jumps when I press w or s and look down or up respectively. My code:
using UnityEngine;
using Unity.Netcode;
public class PlayerMovement : NetworkBehaviour
{
public CharacterController controller;
public float speed = 12f;
// Update is called once per frame
void Update ()
{
if(IsOwner)
{
float x = Input.GetAxis("Horizontal");
float z = Input.GetAxis("Vertical");
Vector3 move = transform.right * x + transform.forward * z;
controller.Move(move.normalized * speed * Time.deltaTime);
}
}
}
I cannot find anything on the matter online, so I came here.
I hope you can help me :)

The following line of code is using the transform's rotation to determine direction of movement. If you look up or down, then your transform.forward is also likely directed up or down.
Vector3 move = transform.right * x + transform.forward * z;
So when you look up and apply a positive z value, your movement is going to move you forward (in the direction you are looking, which is actually up). Due to gravity, you are likely making tiny "jumps" as your character moves up and is pulled down by gravity.
There are a few ways to correct for this, but one potential fix would be to remove the y component of your move vector:
move.y = 0f;

Related

Vector3.Lerp() not smoothing correctly

I'm working on a hand sway system. And the problem is that when I use Vector3.Lerp(); for it, it looks really bad and laggy :
https://streamable.com/64y52o
And this is my source code :
Transform target;
float smooth;
void Update()
{
transform.position = Vector3.Lerp(transform.position, target.transform.position, smooth * Time.deltaTime);
}
And this is my setup in editor :
enter image description here
The script is attached to Hand game object. And the target input is Hand Pos object in inspector.
I tried using both Vector3.Lerp(); and Vector3.Slerp(); but it didn't change anything.
I also tried running code on both Update() and FixedUpdate() and even LateUpdate() but not much changed.
Full code for source :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class HandSway : MonoBehaviour
{
public float smooth;
public float swayMultiplier = 1f;
public Vector3 handOffset;
public Transform target;
private void Update()
{
float x = Input.GetAxisRaw("Mouse X") * swayMultiplier;
float y = Input.GetAxisRaw("Mouse Y") * swayMultiplier;
Quaternion xRot = Quaternion.AngleAxis(-y, Vector3.right);
Quaternion yRot = Quaternion.AngleAxis(x, Vector3.up);
Quaternion rotation = xRot * yRot * target.rotation;
transform.localRotation = Quaternion.Slerp(transform.localRotation, rotation, smooth * Time.deltaTime);
transform.position = Vector3.Lerp(transform.position, target.transform.position, smooth * Time.deltaTime);
}
}
There are a few different approaches when animating an object.
One is to start from position A and interpolate over T seconds to position B. This would be expressed in code like:
t += Time.deltaTime;
transform.position = Vector3.Lerp(A, B, t / T);
This should move the object with a constant speed. If you want to control the speed instead you you could compute T = A.Distance(B) / speed. If you want a constant acceleration instead you could use SLerp.
If you want the object to track the target continuously rather than animating it I would probably not recommend just using Lerp. This will result in a speed that is completely dependent on the distance. This would be equal to a proportional only regulation, see PID controller. Notably, if your proportional factor (i.e. smooth * Time.deltaTime) is larger than 1 you will get oscillations, that might be what is happening.
I would probably recommend that you instead calculate the direction to the target, and cap the speed. You might also want to cap the acceleration for a smoother animation.

How to make a game object move to the opposite direction of a constantly moving object? Unity 2D

I have a game object that constantly rotates around another one:
What I am trying to achieve is to have the circle move in the opposite direction of the square when I press the space key, the square will simulate a propeller, for example:
This is the code I have, which kinda works:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
[SerializeField] GameObject rotatingPropellant;
[SerializeField] float rotationSpeed;
[SerializeField] float impulseForce;
Rigidbody2D playerRb;
void Start()
{
playerRb = GetComponent<Rigidbody2D>();
}
void Update()
{
RotatePropellant();
Move();
}
void RotatePropellant()
{
rotatingPropellant.transform.RotateAround(transform.position, new Vector3(0f, 0f, 1f), rotationSpeed * Time.deltaTime);
}
void Move()
{
if (Input.GetButtonDown("Jump"))
{
playerRb.velocity = -rotatingPropellant.transform.position * impulseForce * Time.deltaTime;
}
}
}
But sometimes the circle moves up even if the square is up (meaning that the circle should be pushed down), not sure if maybe the signs are not correct or if I should be approaching this with a different method
So this:
playerRb.velocity = -rotatingPropellant.transform.position * impulseForce * Time.deltaTime;
relies on rotatingPropellant position relative to World's zero position (Vector3.zero), which might work only if the propellant revolves around this zero point.
What you should probably do instead is get the difference:
Vector3 dir = (rotatingPropellant.transform.position - transform.position).normalized;
playerRb.velocity = dir * impulseForce * Time.deltaTime;
Also, instead of changing velocity, you can add force instead:
Vector3 dir = (rotatingPropellant.transform.position - transform.position).normalized;
playerRb.AddForce(dir * impulseForce, ForceMode2D.Impulse);
To get movement direction, you can use this vector formula AB = B - A. This formula will give you the position vector of A Related to B space and if you normalize this vector you will get the movement direction
A is sphere and B is Square at here. Check Vector Addition and Substraction.

Relative input but global movement in Unity

I'm working on a spaceflight game in unity and stumbled across this simple logical error. I want to be able to add relative movement to my spaceship, but also for it to keep the momentum in that direction when you turn. I've sot a separate script for looking around and movement. Here is my movement source code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public CharacterController ship;
public float speed = 0.001f;
float momentum = 0f;
Vector3 velocity;
void Start()
{
Cursor.lockState = CursorLockMode.Locked;
}
void Update()
{
momentum = momentum + Input.GetAxis("Vertical");
Vector3 move = transform.forward * momentum * 0.001f;
ship.Move(move);
}
}
I know this is a simple question, my brain is just kind of stuck right now. Thanks! ~OwenPT
Do I understand correctly that you want the spaceship fly forward and when it turns right or left it must continue flying forward?
Your spaceship must have component rigidbody (I think it does) and you get mode him using function GetComponent().AddForce. There you can choose the ForceMode. There are 4 kinds of force_mode:
Force - Add a continuous force to the rigidbody, using its mass.
Acceleration - Add a continuous acceleration to the rigidbody, ignoring its mass.
Impulse - Add an instant force impulse to the rigidbody, using its mass.
VelocityChange - Add an instant velocity change to the rigidbody, ignoring its mass.
So, choose the one you need and the spaceship must continue flying forward after turning
You've neglected your velocity variable. You're applying a scalar speed (momentum) in the direction of facing (transform.forward).
If you want to have a feel of momentum, you need to deal with Acceleration:
public CharacterController Ship;
public float AccelerationFactor = 1.0f;
public float BrakingFactor = 0.1f;
public float MaxSpeed = 20.0f;
private Vector3 Velocity;
void Update()
{
var totalBraking = Velocity.normalized * BrakingFactor;
var totalAcceleration = transform.forward * AccelerationFactor * Input.GetAxis("Vertical");
Velocity = Velocity + (totalAcceleration + totalBraking) * Time.deltaTime;
Velocity = Vector3.ClampMagnitude(Velocity, MaxSpeed);
Ship.Move(Velocity * Time.deltaTime);
}

transform.Translate seems to accelerate and decelerate object when reading from Input.GetAxis()

I started using Unity recently and I have a very simple script shown below which moves a sprite left, right, up and down.
using UnityEngine;
using System.Collections;
public class PlayerController : MonoBehaviour {
// Speed set to 5 in Inspector
public int speed;
// Update is called once per frame
void Update () {
var x = Input.GetAxis("Horizontal") * Time.deltaTime * speed;
var y = Input.GetAxis("Vertical") * Time.deltaTime * speed;
transform.Translate (x, y, 0);
}
}
The problem is that when I press the an arrow key, the sprite seems to accelerate for a second or less and when I release the key it seems to decelerate for a second or less. I do not want it to do that, I just want it to have the same speed all of the time without any acceleration or deceleration.
Can you please let me know what I might be doing wrong?
I figured it out by looking at the API.
Input.GetAxis seems to apply a smoothing filter. I found this out or deduced it when I saw the Input.GetAxisRaw function, in its description it says
Returns the value of the virtual axis identified by axisName with no smoothing filtering applied.
Which leads me to believe the Input.GetAxis function applies smoothing.
So the function now reads
void Update () {
var x = Input.GetAxisRaw("Horizontal") * Time.deltaTime * speed;
var y = Input.GetAxisRaw("Vertical") * Time.deltaTime * speed;
transform.Translate (x, y, 0);
}
Thank you all for your time
Regards
Crouz

Unity3D C#. Using the transform.RotateAround() function while keep the distance between two objects constant

I am trying to practice making third person controllers in Unity 3D. I am a beginner, and I am completely baffled on how to make my controller functional. I have been doing hours of research, but no thread I can find seem to answer my question. I have two scripts, a CameraController, and a CharacterController. My code is below.
CameraController:
using UnityEngine;
using System.Collections;
public class CameraController : MonoBehaviour {
public GameObject target;
public float rotationSpeed;
Vector3 offset;
Vector3 CameraDestination;
// Use this for initialization
void Start () {
offset = transform.position - target.transform.position;
CameraDestination = offset + transform.position;
rotationSpeed = 50f;
transform.position = CameraDestination;
}
// Update is called once per frame
void Update () {
transform.LookAt (target.transform.position);
float h = Input.GetAxisRaw ("Horizontal");
transform.RotateAround (target.transform.position, Vector3.up, Time.deltaTime * h * rotationSpeed);
target.transform.Rotate (0f, Time.deltaTime * h * rotationSpeed, 0f);
}
}
CharacterController:
using UnityEngine;
using System.Collections;
public class CharController : MonoBehaviour {
public float playerSpeed = 10f;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
float Vertical = Input.GetAxis("Vertical");
transform.position += transform.forward * Time.deltaTime * playerSpeed * Vertical;
}
}
When either the left or right arrow key is pressed, both the player and the camera rotates. If I try to attach the camera to the player as a children, the camera's rotation becomes messed up, but if I do not attach the camera to the player, the camera stops following the player. If I try to set the camera to a specific position relative to the player, it stops revolving around the player like it is intended to do. I simply can not come up with a method that works.Thank you for answering my question in advance!
When I go about this, I like to have an empty gameObject which has 2 children, the camera and then the mesh of the character.
> CharacterController
> Camera
> CharacterRig
When you want to rotate the character, rotate the CharacterController, then when you want to rotate the Camera around the character, change your code to:
transform.RotateAround (CharacterRig.transform.position, Vector3.up, Time.deltaTime * h * rotationSpeed);
This will allow your camera to rotate irrespective of any character animation and should solve your issue. This is very important if you want to implement animations later, as you don't want to parent the camera to the thing that is being animated because it will move with the animation.
P.s. Your code appears fine. Certain that it is purely the way you have set up the game objects.

Categories

Resources