Hi guys i have a problem with that code:
using UnityEngine;
using UnitySampleAssets.CrossPlatformInput;
namespace CompleteProject
{
public class PlayerMovement : MonoBehaviour
{
public float speed = 6f; // The speed that the player will move at.
Vector3 movement; // The vector to store the direction of the player's movement.
Animator anim; // Reference to the animator component.
Rigidbody playerRigidbody; // Reference to the player's rigidbody.
#if !MOBILE_INPUT
int floorMask; // A layer mask so that a ray can be cast just at gameobjects on the floor layer.
float camRayLength = 100f; // The length of the ray from the camera into the scene.
#endif
void Awake ()
{
#if !MOBILE_INPUT
// Create a layer mask for the floor layer.
floorMask = LayerMask.GetMask ("Floor");
#endif
// Set up references.
anim = GetComponent <Animator> ();
playerRigidbody = GetComponent <Rigidbody> ();
}
void FixedUpdate ()
{
// Store the input axes.
float h = CrossPlatformInputManager.GetAxisRaw("Horizontal");
float v = CrossPlatformInputManager.GetAxisRaw("Vertical");
// Move the player around the scene.
Move (h, v);
// Turn the player to face the mouse cursor.
Turning ();
// Animate the player.
Animating (h, v);
}
void Move (float h, float v)
{
// Set the movement vector based on the axis input.
movement.Set (h, 0f, v);
// Normalise the movement vector and make it proportional to the speed per second.
movement = movement.normalized * speed * Time.deltaTime;
// Move the player to it's current position plus the movement.
playerRigidbody.MovePosition (transform.position + movement);
}
void Turning ()
{
#if !MOBILE_INPUT
// Create a ray from the mouse cursor on screen in the direction of the camera.
Ray camRay = Camera.main.ScreenPointToRay (Input.mousePosition);
// Create a RaycastHit variable to store information about what was hit by the ray.
RaycastHit floorHit;
// Perform the raycast and if it hits something on the floor layer...
if(Physics.Raycast (camRay, out floorHit, camRayLength, floorMask))
{
// Create a vector from the player to the point on the floor the raycast from the mouse hit.
Vector3 playerToMouse = floorHit.point - transform.position;
// Ensure the vector is entirely along the floor plane.
playerToMouse.y = 0f;
// Create a quaternion (rotation) based on looking down the vector from the player to the mouse.
Quaternion newRotatation = Quaternion.LookRotation (playerToMouse);
// Set the player's rotation to this new rotation.
playerRigidbody.MoveRotation (newRotatation);
}
#else
Vector3 turnDir = new Vector3(CrossPlatformInputManager.GetAxisRaw("Mouse X") , 0f , CrossPlatformInputManager.GetAxisRaw("Mouse Y"));
if (turnDir != Vector3.zero)
{
// Create a vector from the player to the point on the floor the raycast from the mouse hit.
Vector3 playerToMouse = (transform.position + turnDir) - transform.position;
// Ensure the vector is entirely along the floor plane.
playerToMouse.y = 0f;
// Create a quaternion (rotation) based on looking down the vector from the player to the mouse.
Quaternion newRotatation = Quaternion.LookRotation(playerToMouse);
// Set the player's rotation to this new rotation.
playerRigidbody.MoveRotation(newRotatation);
}
#endif
}
void Animating (float h, float v)
{
// Create a boolean that is true if either of the input axes is non-zero.
bool walking = h != 0f || v != 0f;
// Tell the animator whether or not the player is walking.
anim.SetBool ("IsWalking", walking);
}
}
}
I have tried many ways , but unfortunately none of them works , I need that my player can jump , and maybe even do a double jump . I just can not figure out how to blow it up .
I say thanks to those who will help me.
You need to use RigidBody's AddForce function: http://docs.unity3d.com/ScriptReference/Rigidbody.AddForce.html
As in the example, use a Vector3.Up multiplied by the force of your jump.
You can include this code in the FidexUpdate function. If the jump key is down (http://docs.unity3d.com/ScriptReference/Input.GetKeyDown.html), then AddForce to the player.
Related
I'm trying to get an object to rotate smoothly on the z axis when it comes into contact with a collider. However it just seems to snap really quickly and I can't find a way to smooth this out.
I've split the rotation out into 2 scenarios - one for when the player enters the collider (which needs to be smooth), and one for when the player is already in the collider (which needs to be snappy). this is so that when the player enters the objects gravity (collider) he'll rotate smoothly before falling to the ground. However, if the player is already within the objects gravitational pull, its snappy so they can run on the ground (a circle) without any wierd floating or rolling occuring.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GravitationalBody : MonoBehaviour
{
[Range(0, 0.3f)] [SerializeField] private float m_OrientationSmoothing = 0.3f; // How much to smooth out the movement
void OnTriggerEnter2D(Collider2D obj) {
// Define direction of gravity
Vector3 gravityDirection = transform.position - obj.transform.position;
// apply gravity to all objects within range
obj.GetComponent<Rigidbody2D>().AddForce(gravityDirection);
orientObjects(obj, gravityDirection, true);
}
void OnTriggerStay2D(Collider2D obj)
{
// Define direction of gravity
Vector3 gravityDirection = transform.position - obj.transform.position;
// apply gravity to all objects within range
obj.GetComponent<Rigidbody2D>().AddForce(gravityDirection);
orientObjects(obj, gravityDirection, false);
}
// Control players Z axis rotation to point toward center of planets
void orientObjects(Collider2D obj, Vector3 gravityDirection, bool lerp)
{
float orientation = 90 + Mathf.Atan2(gravityDirection.y, gravityDirection.x) * Mathf.Rad2Deg;
if (lerp)
{
Quaternion q = Quaternion.AngleAxis(orientation, Vector3.forward);
obj.transform.rotation = Quaternion.Lerp(obj.transform.rotation, q, m_OrientationSmoothing * Time.deltaTime);
}
else obj.transform.rotation = Quaternion.Euler(0f, 0f, orientation);
}
}
I don't know if it will help but if you want a smooth rotation look at this code, I'm sure you can find inspiration here:
[SerializeField] float _degreesPerSecond = 30f;
[SerializeField] Vector3 _axis = Vector3.forward;
void Update ()
{
transform.Rotate( _axis.normalized * _degreesPerSecond * Time.deltaTime );
}
I'm attempting to make the ability to slide in an FPS game I'm working on and I've tried rotating the player object but when tested, it does nothing. Pressing the slide key I have assigned does nothing but rotate the player object in the Y and Z axis (I'm trying to rotate it on the X axis)
Here's the code I'm using (only relevant parts have been kept in):
public class SlideMovementScript : MonoBehaviour
{
public Rigidbody rig;
public CapsuleCollider capcol;
public GameObject player;
public float originalHeight;
public float reducedHeight;
public float slideSpeed = 10f;
// Start is called before the first frame update
void Start()
{
capcol = GetComponent<CapsuleCollider>();
rig = GetComponent<Rigidbody>();
originalHeight = capcol.height;
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.LeftControl) && Input.GetKey(KeyCode.W))
Sliding();
else if (Input.GetKeyUp(KeyCode.LeftControl))
GoUp();
}
private void Sliding()
{
capcol.height = reducedHeight;
player.transform.localRotation = Quaternion.Euler(1.599f, 0f, 0f);
rig.AddForce(transform.forward * slideSpeed, ForceMode.VelocityChange);
}
private void GoUp()
{
GetComponent<CapsuleCollider>().height = originalHeight;
player.transform.localRotation = Quaternion.Euler(0f, 0f, 0f);
}
}
I've gotten ZERO error messages from this but I haven't managed to find the problem
Another problem I've also had is when you start sliding, it just instantly rotates the Player object to X 1.599 Y 0 Z 0. I want it to rotate to where the player is facing but I haven't found a way to do it, even using transform.foward or other references won't work.
The Explanation (skip to script if you want) (read notes)
I reccomend using Quaternion's methods. You can use Quaternion.Slerp which can smooth out the rotation towards the player.
Slerp means spherical linear interpolation
Basically, Slerp is a 3 argumented method. the first argument is the current rotation, the second argument is the target rotation, and the third is at which point between those two you want to output.
More simply, Lerp is linear interpolation. Lerps arguments are the same, except it handles floats and not Quaternions. If you Mathf.Lerp(0,1,1); you will get 1, because 1 is all the ay to the second argument. If you do Mathf(0, 3, 0.5); you will get 1.5 because 1.5 is halfway (0.5) between them both.
You can imagine slerp like that, if you give rotation (90, 0, 0) and alerp it to (0, 0, 0) by 0.5 you will get (45, 0, 0).
On this example, I slerp from the current rotation, to the target rotation, by delta time. This way, as time goes on, it slightly increases the current rotation to be the target.
I can create the target as 1.599 rotated on the x.
To make this relative Make a parent game object to the player containing the mesh and rigidbody and maybe the collider (depends if you want the collider upright). I will call this "slidePlayer" slidePlayer must be a child of the player gameObject
Notes
Make sure to have slidePlayer to a gameObject that is a child of player, but must have the player mesh or sliding won't be visible.
Change rot to the target rotation.
Change speed to speed to rotate to the target rotation.
Here is your script I changed:
public class SlideMovementScript : MonoBehaviour
{
public Rigidbody rig;
public CapsuleCollider capcol;
public GameObject player;
public GameObject slidePlayer;
public float originalHeight;
public float reducedHeight;
public float slideSpeed = 10f;
// Start is called before the first frame update
void Start()
{
capcol = GetComponent<CapsuleCollider>();
rig = GetComponent<Rigidbody>();
originalHeight = capcol.height;
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.LeftControl) && Input.GetKey(KeyCode.W))
Sliding();
else if (Input.GetKeyUp(KeyCode.LeftControl))
GoUp();
}
private void Sliding()
{
capcol.height = reducedHeight;
Quaternion rot = Quaternion.Euler(1.599f, 0f, 0f);
float speed = 1f;
Quaternion curRot = slidePlayer.transform.localRotation;
slidePlayer.transform.localRotation = Quaternion.Slerp(curRot, rot, Time.deltaTime * speed);
rig.AddForce(transform.forward * slideSpeed, ForceMode.VelocityChange);
}
private void GoUp()
{
GetComponent<CapsuleCollider>().height = originalHeight;
Quaternion rot = Quaternion.Euler(0f, 0f, 0f);
float speed = 3f;
Quaternion curRot = slidePlayer.transform.localRotation;
slidePlayer.transform.localRotation = Quaternion.Slerp(curRot, rot, Time.deltaTime * speed);
}
}
Let me know if there are any problems in coments. Thanks.
I’m make a 2D game in unity and I searched for a solution but I did not find anything.
This for a new game in unity
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public float speed = 6f; // The speed that the player will move at.
Vector3 movement; // The vector to store the direction of the player's movement.
Animator anim; // Reference to the animator component.
Rigidbody playerRigidbody; // Reference to the player's rigidbody.
int floorMask; // A layer mask so that a ray can be cast just at gameobjects on the floor layer.
float camRayLength = 100f; // The length of the ray from the camera into the scene.
void Awake ()
{
// Create a layer mask for the floor layer.
floorMask = LayerMask.GetMask ("Floor");
// Set up references.
anim = GetComponent <Animator> ();
playerRigidbody = GetComponent <Rigidbody> ();
}
void FixedUpdate ()
{
// Store the input axes.
float h = Input.GetAxisRaw ("Horizontal");
float v = Input.GetAxisRaw ("Vertical");
// Move the player around the scene.
Move (h, v);
// Turn the player to face the mouse cursor.
Turning ();
// Animate the player.
Animating (h, v);
}
void Move (float h, float v)
{
// Set the movement vector based on the axis input.
movement.Set (h, 0f, v);
// Normalise the movement vector and make it proportional to the speed per second.
movement = movement.normalized * speed * Time.deltaTime;
// Move the player to it's current position plus the movement.
playerRigidbody.MovePosition (transform.position + movement);
}
void Turning ()
{
// Create a ray from the mouse cursor on screen in the direction of the camera.
Ray camRay = Camera.main.ScreenPointToRay (Input.mousePosition);
// Create a RaycastHit variable to store information about what was hit by the ray.
RaycastHit floorHit;
// Perform the raycast and if it hits something on the floor layer...
if(Physics.Raycast (camRay, out floorHit, camRayLength, floorMask))
{
// Create a vector from the player to the point on the floor the raycast from the mouse hit.
Vector3 playerToMouse = floorHit.point - transform.position;
// Ensure the vector is entirely along the floor plane.
playerToMouse.y = 0f;
// Create a quaternion (rotation) based on looking down the vector from the player to the mouse.
Quaternion newRotation = Quaternion.LookRotation (playerToMouse);
// Set the player's rotation to this new rotation.
playerRigidbody.MoveRotation (newRotation);
}
}
void Animating (float h, float v)
{
// Create a boolean that is true if either of the input axes is non-zero.
bool walking = h != 0f || v != 0f;
// Tell the animator whether or not the player is walking.
anim.SetBool ("IsWalking", walking);
}
I tried some codes up here but it doesn't do what I want in my game. There is no health.
You can use the function OnCollisionEnter2D to check if your player collides with an enemy. This function triggers whenever the GameObject enters the hit box of another GameObject
For example:
void OnCollisionEnter2D(Collision2D other) {
if (other.gameObject.tag == "enemy") {
// Gameover... show end screen
}
}
Just don't forget to set the "tags" on your enemies in the editor.
For more information check out the links below
https://docs.unity3d.com/ScriptReference/MonoBehaviour.OnCollisionEnter2D.html
https://answers.unity.com/questions/1408186/how-to-check-if-boxcollider2d-collided-with-anothe.html
I'am assuming you are a new user to unity, so Iam gonna help you with the code a bit more than I usually do.
to detect a collision with an enemy in 2d, we use the function OnCollisionEnter2d and what it does is basically detects collision in 2d and stores the collision's info into a variable, here is the documentation... please read to understand more.
So after you wrote the OnCollisionEnter2d function, inside it you would need to write an if statement that uses the OnCollisionEnter2d info that is stored in a variable. And checks whether the tag of the other game object is compatible with what you wrote in the code.
then you have to make a function(s) to enable and disable the UI components of your game. Since I don't what are those components, I will not write that code in and I will just write some examples. here is some documentation that might help.
here is the code:
void OnCollisionEnter2d(Collision2d other)
{
if (other.gameObject.tag == "enemy")
{
disableEnableUI();
}
}
here is the disableEnableUI(); function:
public GameObject restartButton;
public GameObject gameOverTxt;
void disableEnableUI()
{
restartButton.SetActive(true);
gameOverTxt.SetActive(true);
}
I am following Survival Shooter unity tutorial and in the tutorial the down given code is used to make the camera follow the player.The code is working but how can i alter it so that it stops following the player at a given X and Y point.
code
public Transform target; // The position that that camera will be following.
public float smoothing = 5f; // The speed with which the camera will be following.
Vector3 offset; // The initial offset from the target.
void Start ()
{
// Calculate the initial offset.
offset = transform.position - target.position;
}
void FixedUpdate ()
{
// Create a postion the camera is aiming for based on the offset from the target.
Vector3 targetCamPos = target.position + offset;
// Smoothly interpolate between the camera's current position and it's target position.
transform.position = Vector3.Lerp (transform.position, targetCamPos, smoothing * Time.deltaTime);
}
Simply stop updating his position:
private bool followPlayer = true;
void FixedUpdate ()
{
if(followPlayer){
// Create a postion the camera is aiming for based on the offset from the target.
Vector3 targetCamPos = target.position + offset;
// Smoothly interpolate between the camera's current position and it's target position.
transform.position = Vector3.Lerp (transform.position, targetCamPos, smoothing * Time.deltaTime);
}
}
Change the value of followPlayer to false and it will stop following
To determine if the player is at given point, you need to check distance between the player and the point, e.g:
public Transform target; // player position
public Transform stopingPoint; // stopping point position
public double tolerance; // the "radius" of stopping point
private bool followPlayer = true;
...
void FixedUpdate ()
{
if(!followPlayer)
return;
followPlayer = Vector3.Distance(target.position, stopingPoint.position) <= tolerance;
...
I know I should have posted this question on Unity's questions page but I actually did and haven't received an answer for 3 days.
So I'm trying to make the character face the direction it is moving but I can't make it work. I'm working on a 3d game with a diablo-style camera but without depending on the mouse, and I'm using the script from 'Survival Shooter' as a reference.
Here's the movement script:
public float speed = 6f; // The speed that the player will move at.
public float rotateSpeed = 2f;
public Camera playerCam;
Vector3 movement; // The vector to store the direction of the player's movement.
Animator anim; // Reference to the animator component.
Rigidbody playerRigidbody; // Reference to the player's rigidbody.
int floorMask; // A layer mask so that a ray can be cast just at gameobjects on the floor layer.
float camRayLength = 100f; // The length of the ray from the camera into the scene.
Vector3 rotationY;
void Awake ()
{
// Create a layer mask for the floor layer.
floorMask = LayerMask.GetMask ("Floor");
// Set up references.
anim = GetComponent <Animator> ();
playerRigidbody = GetComponent <Rigidbody> ();
}
void FixedUpdate ()
{
// Store the input axes.
float h = Input.GetAxisRaw ("Horizontal");
float v = Input.GetAxisRaw ("Vertical");
// Move the player around the scene.
Move (h, v);
// Turn the player to face the mouse cursor.
Turning (h, v);
}
void Move (float h, float v)
{
// Move the player to it's current position plus the movement.
Vector3 targetDirection = new Vector3(h, 0f, v);
targetDirection = Camera.main.transform.TransformDirection(targetDirection);
targetDirection = targetDirection.normalized * speed * Time.deltaTime;
targetDirection.y = 0.0f;
playerRigidbody.MovePosition (transform.position + targetDirection);
}
void Turning(float y, float x)
{
if (y != 0) {
rotationY.Set (0f, y, 0f);
//rotationY = rotationY.normalized * (5 * rotateSpeed);
Quaternion deltaRotation = Quaternion.Euler (rotationY);
playerRigidbody.MoveRotation (deltaRotation);
}
}
However when I move the character it always faces the bottom-left side of the screen. How can I fix that?