As you may know, the mode for the configurable spring has been removed, and I've discovered this following a Brackeys tutorial on multiplayer fps (part 5). There was a comment under the video saying that you should ignore this as Brackeys sets it manually in the code later. However, when I did this, there was no errors, but the jump button did nothing (yes I checked the inputs)
My code is below:
using UnityEngine;
[RequireComponent(typeof(PlayerMotor))]
[RequireComponent(typeof(ConfigurableJoint))]
public class PlayerController : MonoBehaviour
{
private Vector3 _movHorizontal;
private Vector3 _movVertical;
private Vector3 _velocity;
[SerializeField]
private float speed = 5f;
[SerializeField]
private float lookSensitivity = 5f;
[SerializeField]
private float thrusterForce = 1000f;
[Header("Spring Settings:")]
[SerializeField]
private JointDriveMode jointMode = JointDriveMode.Position;
[SerializeField]
private float jointSpring = 20f;
[SerializeField]
private float joinMaxForce = 40f;
private PlayerMotor motor;
private ConfigurableJoint joint;
void Start ()
{
motor = GetComponent<PlayerMotor>();
joint = GetComponent<ConfigurableJoint>();
SetJointSettings(jointSpring);
}
void Update ()
{
//Calc movement velocity as Vector 3D
float _xMov = Input.GetAxisRaw("Horizontal");
float _zMov = Input.GetAxisRaw("Vertical");
_movHorizontal = transform.right * _xMov;
_movVertical = transform.forward * _zMov;
//Final movement vector
_velocity = (_movHorizontal + _movVertical).normalized * speed;
//Apply movement
motor.Move(_velocity);
//Calculate rotation as a 3d vector (turning around)
float _yrot = Input.GetAxisRaw("Mouse X");
Vector3 _rotation = new Vector3 (0f, _yrot, 0f) * lookSensitivity;
//Apply rotation
motor.Rotate(_rotation);
//Calculate rotation as a 3d vector (turning around)
float _xrot = Input.GetAxisRaw("Mouse Y");
Vector3 _cameraRotation = new Vector3 (_xrot, 0f, 0f) * lookSensitivity;
//Apply rotation
motor.RotateCamera(_cameraRotation);
//Calculate thruster force based on player input
Vector3 _thrusterForce = new Vector3 (0, 0, 0);
if (Input.GetButton("Jump"))
{
_thrusterForce = Vector3.up * thrusterForce;
SetJointSettings(0f);
} else
{
SetJointSettings(jointSpring);
}
//Apply thruster force
motor.ApplyThruster(_thrusterForce);
}
private void SetJointSettings(float _jointSpring)
{
joint.yDrive = new JointDrive
{
mode = jointMode,
positionSpring = _jointSpring,
maximumForce = joinMaxForce
};
}
}
Related
I´ve followed a youtube tutorial https://www.youtube.com/watch?v=c1FYp1oOFIs&list=PLD_vBJjpCwJtrHIW1SS5_BNRk6KZJZ7_d&index=4
and the problem is when i start the game my camera moves up when it shouldnt.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace BARR3TT
{
public class CameraHandler : MonoBehaviour
{
public Transform targetTransform;
public Transform cameraTransform;
public Transform cameraPivotTransform;
private Transform myTransform;
private Vector3 cameraTransformPosition;
private LayerMask ignoreLayers;
private Vector3 cameraFollowVelocity = Vector3.zero;
public static CameraHandler singleton;
public float lookSpeed = 0.1f;
public float followSpeed = 0.1f;
public float pivotSpeed = 0.03f;
private float targetPosition;
private float defaultPosition;
private float lookAngle;
private float pivotAngle;
public float minimumPivot = -35;
public float maximumPivot = 35;
private float cameraSphereRadius = 0.2f;
public float cameraColisionOffset = 0.2f;
public float minimumColisionOffset = 0.2f;
private void Awake()
{
singleton = this;
myTransform = transform;
defaultPosition = cameraTransform.localPosition.z;
ignoreLayers = ~(1 << 8 | 1 << 9 << 10);
}
public void FollowTarget(float delta)
{
Vector3 targetPosition = Vector3.SmoothDamp(myTransform.position, targetTransform.position, ref cameraFollowVelocity, delta / followSpeed);
myTransform.position = targetPosition;
HandleCameraCollision(delta);
}
public void HandleCameraRotation(float delta, float mouseXInput, float mouseYInput)
{
lookAngle += (mouseXInput * lookSpeed) / delta;
pivotAngle -= (mouseYInput * pivotSpeed) / delta;
pivotAngle = Mathf.Clamp(pivotAngle, minimumPivot, maximumPivot);
Vector3 rotation = Vector3.zero;
rotation.y = lookAngle;
Quaternion targetRotation = Quaternion.Euler(rotation);
myTransform.rotation = targetRotation;
rotation = Vector3.zero;
rotation.x = pivotAngle;
targetRotation = Quaternion.Euler(rotation);
cameraPivotTransform.localRotation = targetRotation;
}
private void HandleCameraCollision(float delta)
{
targetPosition = defaultPosition;
RaycastHit hit;
Vector3 direction = cameraTransform.position - cameraPivotTransform.position;
direction.Normalize();
if(Physics.SphereCast(cameraPivotTransform.position, cameraSphereRadius, direction, out hit ,Mathf.Abs(targetPosition)))
{
float dis = Vector3.Distance(cameraPivotTransform.position, hit.point);
targetPosition = -(dis - cameraColisionOffset);
}
if(Mathf.Abs(targetPosition)<minimumColisionOffset)
{
targetPosition = -minimumColisionOffset;
}
cameraTransformPosition.z = Mathf.Lerp(cameraTransform.localPosition.z, targetPosition, delta / 0.2f);
cameraTransform.localPosition = cameraTransformPosition;
}
}
}
Ive checked every line and i dont see any mistakes the transforms are where they should be, i can kinda fix it adding some rotation in the x axis on the main camera but its still weird
You need to check if your camera has been attached to any script or if it is a child inside some objects. I think it is where the error comes from.
If the Camera Holder or Camera Pivot changes its direction so the Main Camera will be changed too.
Your code is very complicated and it doesn't have any comments. So that is why people when seeing your code are lazy to see, analyze and answer for you.
If you just begin with coding and I recommend that you need to build a good foundation first and then go to some difficult tutorials like those you followed. Don't follow step-by-step tutorials.
I'm creating a simple movement/following script in C#. I have a prefab (ball) spawn randomly within the Awake() method, at a random area in my scene. I then have another script attached to a different game object (robot) that at the start of the game shall move towards the ball.
Now the movement works but when the game object has come into the the minDistanceToTarget it begins to "jitter" and move around.
Here's the movement script:
public class RobotMovement : MonoBehaviour {
// Movement
private Transform target;
private float speed = 2f;
private float distance;
private float minDistanceToTarget = 1f;
// Rotation
private Vector3 targetDirection;
private Quaternion lookAtRotation;
private float RotationSpeed = 2f;
void Start() {
target = GameObject.FindGameObjectWithTag("Ball").transform;
}
void Update() {
targetDirection = target.position - transform.position;
lookAtRotation = Quaternion.LookRotation(targetDirection);
transform.rotation = Quaternion.Slerp(transform.rotation, lookAtRotation, RotationSpeed * Time.deltaTime);
distance = Vector3.Distance(transform.position, target.position);
if (distance >= minDistanceToTarget) {
transform.position = Vector3.MoveTowards(transform.position, target.position, speed * Time.deltaTime);
}
}
}
Edit I tried to change the affect to use FixedUpdate and affect the RigidBodies instead.
public class RobotMovement : MonoBehaviour {
private Rigidbody robot;
public Rigidbody target;
// Movement
private float speed = 2f;
private float minDistanceToTarget = 2f;
void Start() {
robot = GetComponent<Rigidbody>();
target = target.GetComponent<Rigidbody>();
}
void FixedUpdate() {
if (Vector3.Distance(robot.position, target.position) > minDistanceToTarget) {
robot.MovePosition(target.position * speed * Time.deltaTime);
}
}
}
Edit I now use a new movement method and include a rotation calculation. But it still jumps and jitters
public class RobotMovement : MonoBehaviour {
private Rigidbody robot;
private Transform ball;
// Movement
private float robotMovSpeed = 2f;
private float distanceToTarget;
private float distanceToStop = 2f;
// Rotation
private Vector3 targetDirection;
private Quaternion lookAtTarget;
private float rotationSpeed = 2f;
void Start() {
robot = GetComponent<Rigidbody>();
ball = GameObject.FindGameObjectWithTag("Ball").transform;
}
void FollowTarget(Transform target, float distanceToStop, float speed) {
distanceToTarget = Vector3.Distance(robot.position, target.position);
// Rotation
targetDirection = target.position - robot.position;
lookAtTarget = Quaternion.LookRotation(targetDirection);
if (distanceToTarget >= distanceToStop) {
transform.rotation = Quaternion.Slerp(transform.rotation, lookAtTarget, rotationSpeed * Time.deltaTime);
robot.MovePosition(robot.position + (target.position - robot.position).normalized * speed * Time.deltaTime);
}
}
void FixedUpdate() {
FollowTarget(ball, distanceToStop, robotMovSpeed);
}
}
Hi I am very new to Unity and only got basic knowledge. I created a player who can move and also a camera which follows the player and according to the mouseX and mouseY acis the camera rotates.
Now I want the camera rotation angle to be the forward position.
If the player press w he moves along x acis but if the camera angle change and the player press w it should move into this direction.
player.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DoublePlayer : MonoBehaviour
{
private CharacterController _controller;
public float _jumpHeight = 3f;
[SerializeField]
private float _moveSpeed = 5f;
[SerializeField]
private float _gravity = 9.81f;
private float _directionY;
void Start()
{
_controller = GetComponent<CharacterController>();
}
// Update is called once per frame
void Update()
{
float horizontalInput = Input.GetAxis("Horizontal");
float verticalInput = Input.GetAxis("Vertical");
Vector3 direction = new Vector3(horizontalInput, 0, verticalInput);
// set gravity
_directionY -= _gravity * Time.deltaTime;
direction.y = _directionY;
_controller.Move(direction * _moveSpeed * Time.deltaTime);
}
}
camera.cs
public class CameraController : MonoBehaviour
{
public float RotationSpeed = 1;
public Transform Target, Player;
float mouseX, mouseY;
void Start()
{
Cursor.visible = false;
Cursor.lockState = CursorLockMode.Locked;
}
// Update is called once per frame
void LateUpdate()
{
CamControl();
}
void CamControl()
{
mouseX += Input.GetAxis("Mouse X") * RotationSpeed;
mouseY += Input.GetAxis("Mouse Y") * RotationSpeed;
mouseY = Mathf.Clamp(mouseY, -35, 60);
transform.LookAt(Target);
Target.rotation = Quaternion.Euler(mouseY, mouseX, 0);
Player.rotation = Quaternion.Euler(0, mouseX, 0);
}
}
For Target and Player variable I selected the player object.
Do someone has a simple solution I can understand?
You could simply take the direction and rotate it along with the object that component is attached to using Quaternion * Vector3 operator
var rotatedDirection = transform.rotation * direction;
Or if you rather need the orientation of the other script attached to a different object then do e.g.
// link your camera or whatever shall be used for the orientation via the Inspector
[SerializeField] private Transform directionProvider;
and then
var rotatedDirection = directionProvider.rotation * direction;
Since you're getting the rotation directly from a Transform, you could use Transform.TransformDirection:
Vector3 rotatedDirection = transform.TransformDirection(direction);
I created a FPS Movement script in unity3d for bunny hopping with references from there, but I have some issues.When I am strafing fast my speed decreases.
I wanted to create something like this
This is my code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Movement : MonoBehaviour {
//Strafe Variables
public float gravity = 3f;
public float ground_accelerate = 50f;
public float max_velocity_ground = 4f;
public float air_accelerate = 150f;
public float max_velocity_air = 2f;
public float friction = 8;
bool onGround;
public float jump_force = 5f;
private Vector3 lastFrameVelocity = Vector3.zero;
public Camera camObj;
Rigidbody rb;
Collider coll;
void Start () {
rb = GetComponent<Rigidbody> ();
coll = GetComponent<Collider> ();
}
void Update () {
Vector2 input = new Vector2 (Input.GetAxis ("Horizontal"), Input.GetAxis ("Vertical"));
Vector3 tempVelocity = CalculateFriction(rb.velocity);
tempVelocity += CalculateMovement (input, tempVelocity);
rb.velocity = tempVelocity;
lastFrameVelocity = rb.velocity;
rb.velocity += new Vector3(0f,-gravity,0f) * Time.deltaTime;
}
public Vector3 CalculateFriction(Vector3 currentVelocity)
{
onGround = Grounded();
float speed = currentVelocity.magnitude;
//Code from https://flafla2.github.io/2015/02/14/bunnyhop.html
if (!onGround || Input.GetButton("Jump") || speed == 0f)
return currentVelocity;
float drop = speed * friction * Time.deltaTime;
return currentVelocity * (Mathf.Max(speed - drop, 0f) / speed);
}
//Do movement input here
public Vector3 CalculateMovement(Vector2 input, Vector3 velocity)
{
onGround = Grounded();
//Different acceleration values for ground and air
float curAccel = ground_accelerate;
if (!onGround)
curAccel = air_accelerate;
//Ground speed
float curMaxSpeed = max_velocity_ground;
//Air speed
if (!onGround)
curMaxSpeed = max_velocity_air;
//Get rotation input and make it a vector
Vector3 camRotation = new Vector3(0f, camObj.transform.rotation.eulerAngles.y, 0f);
Vector3 inputVelocity = Quaternion.Euler(camRotation) *
new Vector3(input.x * air_accelerate, 0f, input.y * air_accelerate);
//Ignore vertical component of rotated input
Vector3 alignedInputVelocity = new Vector3(inputVelocity.x, 0f, inputVelocity.z) * Time.deltaTime;
//Get current velocity
Vector3 currentVelocity = new Vector3(velocity.x, 0f, velocity.z);
//How close the current speed to max velocity is (1 = not moving, 0 = at/over max speed)
float max = Mathf.Max(0f, 1 - (currentVelocity.magnitude / curMaxSpeed));
//How perpendicular the input to the current velocity is (0 = 90°)
float velocityDot = Vector3.Dot(currentVelocity, alignedInputVelocity);
//Scale the input to the max speed
Vector3 modifiedVelocity = alignedInputVelocity*max;
//The more perpendicular the input is, the more the input velocity will be applied
Vector3 correctVelocity = Vector3.Lerp(alignedInputVelocity, modifiedVelocity, velocityDot);
//Apply jump
correctVelocity += GetJumpVelocity(velocity.y);
//Return
return correctVelocity;
}
private Vector3 GetJumpVelocity(float yVelocity)
{
Vector3 jumpVelocity = Vector3.zero;
//Calculate jump
if ( Input.GetButton("Jump") && yVelocity < jump_force && Grounded())
{
jumpVelocity = new Vector3(0f, jump_force - yVelocity, 0f);
}
return jumpVelocity;
}
bool Grounded(){
return Physics.Raycast (transform.position, Vector3.down, coll.bounds.extents.y + 0.1f);
}
}
For the entire day, I been trying to find a good solution to completely stop the player from going offscreen without hard coding.
I have this script called player controller and all it does so far is allow the player to move along the x-axis. It also has an additional function that clamps the player's movement in the x-axis. Here it is.
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public const float MAX_SPEED = 5.0f;
// Update is called once per frame
void Update()
{
transform.Translate(Input.GetAxis("Horizontal") * MAX_SPEED * Time.deltaTime, 0.0f, 0.0f);
clampPlayerMovement();
}
void clampPlayerMovement()
{
Vector3 pos = Camera.main.WorldToViewportPoint(transform.position);
pos.x = Mathf.Clamp01(pos.x);
transform.position = Camera.main.ViewportToWorldPoint(pos);
}
}
The problem with this script is that it doesn't completely stops the player from going offscreen(half of the player's body still goes offscreen).
So this is what I tried next.
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public const float MAX_SPEED = 5.0f;
private float xLeft;
private float xRight;
void Start()
{
float pivotX = GetComponent<SpriteRenderer>().sprite.pivot.x;
float pixelsPerunit = GetComponent<SpriteRenderer>().sprite.pixelsPerUnit;
float textureWidth = GetComponent<SpriteRenderer>().sprite.texture.width;
//Units on the left from the sprite's pivot.
xLeft = pivotX / pixelsPerunit;
//Units on the right from the sprite's pivot.
xRight = (textureWidth - pivotX) / pixelsPerunit;
}
// Update is called once per frame
void Update()
{
transform.Translate(Input.GetAxis("Horizontal") * MAX_SPEED * Time.deltaTime, 0.0f, 0.0f);
clampPlayersMovement();
}
void clampPlayersMovement()
{
Vector3 pos = transform.position;
Vector3 posMin = transform.position;
Vector3 posMax = transform.position;
posMin.x = posMin.x - xLeft;
posMax.x = posMax.x + xRight;
pos = Camera.main.WorldToViewportPoint(pos);
posMin = Camera.main.WorldToViewportPoint(posMin);
posMax = Camera.main.WorldToViewportPoint(posMax);
pos.x = Mathf.Clamp(pos.x, posMin.x, posMax.x);
transform.position = Camera.main.ViewportToWorldPoint(pos);
}
}
Unfortunately, this code is no good. In fact, it is even worse because it does not stop the player from going offscreen at all.
So at this point I'm stuck between a rock and a hard place. Any suggestions would be vastly appreciated.
After long searching I finally found an answer.
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public const float MAX_SPEED = 5.0f;
private float halfPlayerSizeX;
void Start()
{
halfPlayerSizeX = GetComponent<SpriteRenderer>().bounds.size.x / 2;
}
// Update is called once per frame
void Update()
{
transform.Translate(Input.GetAxis("Horizontal") * MAX_SPEED * Time.deltaTime, 0.0f, 0.0f);
clampPlayerMovement();
}
void clampPlayerMovement()
{
Vector3 position = transform.position;
float distance = transform.position.z - Camera.main.transform.position.z;
float leftBorder = Camera.main.ViewportToWorldPoint(new Vector3(0, 0, distance)).x + halfPlayerSizeX;
float rightBorder = Camera.main.ViewportToWorldPoint(new Vector3(1, 0, distance)).x - halfPlayerSizeX;
position.x = Mathf.Clamp(position.x, leftBorder, rightBorder);
transform.position = position;
}
}
The only thing that I don't get is why do I need to subtract the z position from both the gameobject and the camera? why not the x position?