I try to create a timer can it start when the player destroy the object.
I need, when the player destroy the object call "test", start a timer and for 10 seconds the player speed is change, from 5f to 10f. When the timer is 10 or more i need the player speed come back to 5f.
This is my code:
using UnityEngine;
using UnityEngine.UI;
using UnitySampleAssets.CrossPlatformInput;
namespace CompleteProject
{
public class PlayerMovement : MonoBehaviour
{
public static float speed = 5f;
public float timer = 5.0f;
float timerMin = 1.0f;
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 ()
{
timer += Time.deltaTime;
// 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 Update ()
{
if(Input.GetKeyUp(KeyCode.Space))
{
}
}
void OnCollisionEnter (Collision col)
{
if(col.gameObject.name == "coin10")
{
Destroy(col.gameObject);
CoinManager.coin=CoinManager.coin+10;
}
if(col.gameObject.name == "coin5")
{
Destroy(col.gameObject);
CoinManager.coin=CoinManager.coin+5;
}
if(col.gameObject.name == "coin1")
{
Destroy(col.gameObject);
CoinManager.coin=CoinManager.coin+1;
}
if(col.gameObject.name == "eterium1")
{
Destroy(col.gameObject);
EteriumManager.eterium=EteriumManager.eterium+1;
}
if(col.gameObject.name == "test")
{
}
}
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);
}
}
}
And this is the part where i need the timer start:
if(col.gameObject.name == "test")
{
}
I have try with timer -= time.deltatime but time.deltatime is not a timer. The value of the timer is the value of the object destroy.
Everyone can help me to do this timer?
Example:
if(timer<=10){
speed=10f;
}
else
{
speed=5f;
}
Use a Coroutine.
Start the Coroutine.
Change the player_speed.
Wait your time.
Reset the speed.
if(col.gameObject.name == "test")
{
StartCoroutine("SlowSpeed");
}
private IEnumerator SlowSpeed()
{
player_speed = 10;
yield return new WaitForSeconds(10f);
player_speed = 5;
}
Related
I have a cloud which has a polygon collider 2d attached. Also, I have a player that has a box collider 2d attached. When the player lands on the cloud, at some point during the movement, something is stopping him. He is animating but he does not move.
Below is the image of my colliders:
When I start running the game, he moves left and right. So I figured it is not a code issue. At a point, he is stuck at the above position and he cannot move right but he can move left. I guess the polygon collider is stopping him from free movement. When I go back, he is walking and when the reaches the above position, he cannot move forward.
Is there any workaround for this?
Below is my code:
public class Player : MonoBehaviour
{
public float speed = 7f;
public float maxVelocity = 8f;
private Rigidbody2D rb;
private Animator anim;
void Awake()
{
rb = GetComponent<Rigidbody2D>();
anim = GetComponent<Animator>();
}
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void FixedUpdate()
{
MovePlayerUsingKeyboard();
}
public void MovePlayerUsingKeyboard()
{
float forceX = 0f;
float velocity = Mathf.Abs(rb.velocity.x);
Debug.Log("Player Velocity : " + velocity);
float direction = Input.GetAxis("Horizontal");
if (direction < 0)
{
if (maxVelocity > velocity)
{
anim.SetBool("Walk", true);
forceX = -speed;
}
//Changing the direction the player faces
Vector3 temp = transform.localScale;
temp.x = -1.3f;
transform.localScale = temp;
}
else if (direction > 0)
{
if (maxVelocity > velocity)
{
anim.SetBool("Walk", true);
forceX = speed;
}
Vector3 temp = transform.localScale;
temp.x = 1.3f;
transform.localScale = temp;
}
else
{
anim.SetBool("Walk", false);
}
rb.AddForce(new Vector2(forceX, 0));
}
}
I think it is because that the collider of your character is stuck at the bumpy part of the cloud's polygon collider.
A solution is to change the character's collider to semi-capsule collider or capsule collider so that the character can walk smoothly on some rough surfaces.
There is a strange behavior when my spaceship fires off some missiles to destroy an enemy. Under certain circumstances, the missiles "jump" and fly away.
This seems to happen when the nearest enemy is destroyed by one missile and all others have no target any more. Then they "jump" and fly away (off the screen).
I still don't know the cause of this problem.
void Start () {
rb = this.GetComponent<Rigidbody2D>();
nearestEnemy = FindClosestTarget("EnemyShipTag");
}
Getting the closest target (enemy)
GameObject FindClosestTarget(string _target) {
enemies = GameObject.FindGameObjectsWithTag(_target);
closest = null;
distance = Mathf.Infinity;
_position = this.transform.position;
foreach (GameObject enemy in enemies) {
diff = enemy.transform.position - _position;
curDistance = diff.sqrMagnitude;
if (curDistance < distance) {
closest = enemy;
distance = curDistance;
}
}
return closest;
}
Calculate movement to nearest enemy if nearestEnemy is not null
void FixedUpdate () {
if (nearestEnemy != null) {//is enemy available?
Vector2 enemyTarget = nearestEnemy.transform.position;
Vector2 direction = (Vector2)enemyTarget - rb.position;
direction.Normalize ();
float rotateAmount = Vector3.Cross (direction, transform.up).z;
rb.angularVelocity = -rotateAmount * rotateSpeed;
float speed = 6f;
float step = speed * Time.deltaTime;
transform.position = Vector3.MoveTowards(transform.position, nearestEnemy.transform.position, step);
} else {
//rocket shall fly straight ahead if there's no target
rb.velocity = transform.up * speed;
}
These functions are part of the EnemyControl.cs-script
void OnTriggerEnter2D (Collider2D col) {//this function will trigger when there is a collision of our game objects
//detect collision of the enemy ship with the player ship, or with a player's bullet
if ((col.tag == "PlayerShipTag") || (col.tag == "MissileUpgradeTag")) {
EnemyDestroyed ();
}
void EnemyDestroyed () {
Destroy (gameObject);//Destroy the enemy ship
dead = true;
PlayerControl.enemiesDestroyed++;
}
I am making a thirdperson Unity game. I think that I'm almost done but I just can't figure out how to make so the WASD control is relative to the camera?
Right now when I'm moving with WASD it works, but if i start to rotate the camera by using mouse, suddenly my (W) button makes the player walk backwards and left button (A) goes right. All controls are just bugging.
This is my PlayerMovement.cs and CameraFollow.cs:
PlayerMovement:
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 = 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);
Shooting ();
}
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 newRotatation = Quaternion.LookRotation (playerToMouse);
// Set the player's rotation to this new rotation.
playerRigidbody.MoveRotation (newRotatation);
}
}
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);
}
void Shooting ()
{
// Create a boolean that is true if either of the input axes is non-zero.
bool shooting = (Input.GetMouseButtonDown(0));
// Tell the animator whether or not the player is walking.
anim.SetBool ("IsShooting", shooting);
}
CameraFollow:
// Camera target to look at.
public Transform target;
// Exposed vars for the camera position from the target.
public float height = 20f;
public float distance = 20f;
// Camera limits.
public float min = 10f;
public float max = 60;
// Rotation.
public float rotateSpeed = 1f;
// Options.
public bool doRotate;
public bool doZoom;
// The movement amount when zooming.
public float zoomStep = 30f;
public float zoomSpeed = 5f;
private float heightWanted;
private float distanceWanted;
// Result vectors.
private Vector3 zoomResult;
private Quaternion rotationResult;
private Vector3 targetAdjustedPosition;
void Start(){
// Initialise default zoom vals.
heightWanted = height;
distanceWanted = distance;
// Setup our default camera. We set the zoom result to be our default position.
zoomResult = new Vector3(0f, height, -distance);
}
void LateUpdate(){
// Check target.
if( !target ){
Debug.LogError("This camera has no target, you need to assign a target in the inspector.");
return;
}
if( doZoom ){
// Record our mouse input. If we zoom add this to our height and distance.
float mouseInput = Input.GetAxis("Mouse ScrollWheel");
heightWanted -= zoomStep * mouseInput;
distanceWanted -= zoomStep * mouseInput;
// Make sure they meet our min/max values.
heightWanted = Mathf.Clamp(heightWanted, min, max);
distanceWanted = Mathf.Clamp(distanceWanted, min, max);
height = Mathf.Lerp(height, heightWanted, Time.deltaTime * zoomSpeed);
distance = Mathf.Lerp(distance, distanceWanted, Time.deltaTime * zoomSpeed);
// Post our result.
zoomResult = new Vector3(0f, height, -distance);
}
if( doRotate ){
// Work out the current and wanted rots.
float currentRotationAngle = transform.eulerAngles.y;
float wantedRotationAngle = target.eulerAngles.y;
// Smooth the rotation.
currentRotationAngle = Mathf.LerpAngle(currentRotationAngle, wantedRotationAngle, rotateSpeed * Time.deltaTime);
// Convert the angle into a rotation.
rotationResult = Quaternion.Euler(0f, currentRotationAngle, 0f);
}
// Set the camera position reference.
targetAdjustedPosition = rotationResult * zoomResult;
transform.position = target.position + targetAdjustedPosition;
// Face the desired position.
transform.LookAt(target);
}
Your 'movement' vector should not be independent of camera forward vector, if you want a normal 3-rd person movement. Instead of moving in the 'h' or 'v' directions, move in camera.right and camera.forward directions, multiplied by 'h' and 'v' magnitudes respectively.
To be more accurate, if your camera is slightly inclined (so that its forward will go downward), you should first project camera.forward onto [player.forward, player.right] plane. Unity has a helper function just for that (Vector3.ProjectOnPlane()). If your camera also rotates around its forward direction (e.g. camera shake), you should also project camera.right on the same plane.
// Set the movement vector based on the axis input.
movement.Set (camera.right * h, 0f, camera.forward * v);
I'm trying to understand the code of the PlayerController made by Unity(Survival Shooter Tutorial).I understand everything, except the reason, why they wrote the difference between FLOOR-POINT(where the mouse is directed) and the player (transform position).I tried to write only the floor point without the player position and its worked.Why they wrote that? Maybe someone passed this tutorial and can help me with that?
Unity tutorial : https://unity3d.com/learn/tutorials/projects/survival-shooter/player-character?playlist=17144
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public float speed= 6f;
Vector3 movement;
Animator anim;
Rigidbody playerRigidbody;
int floorMask;
float camRayLength=100f;
void Awake()
{
floorMask = LayerMask.GetMask("Floor");
anim = GetComponent<Animator> ();
playerRigidbody = GetComponent<Rigidbody> ();
}
void FixedUpdate()
{
float v = Input.GetAxisRaw ("Vertical");
float h = Input.GetAxisRaw ("Horizontal");
Move (h, v);
Turning ();
Animating(h,v);
}
void Move(float h,float v)
{
movement.Set (h,0f,v);
movement = movement.normalized * speed * Time.deltaTime;
playerRigidbody.MovePosition (transform.position+movement);
}
void Turning()
{
Ray camRay = Camera.main.ScreenPointToRay (Input.mousePosition);
RaycastHit floorHit;
if(Physics.Raycast(camRay,out floorHit,camRayLength,floorMask))
{
Vector3 playerToMouse = floorHit.point-transform.position ;********
playerToMouse.y = 0f;
Quaternion newRotation = Quaternion.LookRotation (playerToMouse);
playerRigidbody.MoveRotation (newRotation);
}
}
void Animating(float h,float v)
{
bool wakling = h != 0f || v != 0f;
anim.SetBool("IsWalking",wakling);
}
}
Raycasts need a direction, which is usually given as (someVector - someOtherVector). The result from this subtraction is a new vector that takes someVector as the origin point. In your case, the relative vector from the mouse to the player probably never changes, so the subtraction seems not needed. However, it is good practice to use the subtraction of two vectors as direction.
I am learning Unity Game development .. I was following https://unity3d.com/learn/tutorials/projects/survival-shooter/player-character?playlist=17144
Did everything same but,
I want the player object to rotate towards the mouse pointer. But it's not rotating towards mouse pointer..
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
Vector3 movement;
Animator anim;
Rigidbody playerRigidbody;
int floormask;
float camraylength = 100f;
float speed = 10f;
void Awake()
{
anim = GetComponent<Animator>();
floormask = LayerMask.GetMask("floor");
playerRigidbody = GetComponent<Rigidbody>();
}
void FixedUpdate()
{
float h = Input.GetAxisRaw("Horizontal");
float v = Input.GetAxisRaw("Vertical");
moving(h, v);
tunning();
animationz(h, v);
}
void moving(float h, float v)
{
movement = new Vector3(h, 0, v);
movement = movement.normalized * speed * Time.deltaTime;
playerRigidbody.MovePosition(transform.position + movement);
}
void tunning()
{
Ray camray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit floorhit;
if(Physics.Raycast(camray,out floorhit, camraylength, floormask))
{
Vector3 playertomouse = floorhit.point - transform.position;
playertomouse.y = 0f;
Quaternion newrotate = Quaternion.LookRotation(playertomouse);
playerRigidbody.MoveRotation(newrotate);
}
}
void animationz(float h, float v)
{
bool walking = h != 0f || v != 0f;
anim.SetBool("IsWalking", walking);
}
}
The tunning() method is in the above code
If anything more you want then please comment. Thank you for the help...
I suggest you check several stuff to find the source of the problem:
You need to make sure you are using a Quad not a Plane and that the correct face is upwards
Make sure the layer of the quad is "floor" (it's case sensitive)
Make sure the camera is not further than the 100f of the ray you are casting
And finally add a Debug.Log() inside the if condition to check if the ray hits the floor at all.