I have a Cube(player) and a Plane(floor) in my Scene. Both have Colliders attached to them and there is a RigidBody component attached only to the Cube. Cube is placed on the Plane.
LOGS
I don't understand why am I getting those last 3 values.(These too are values for dis value)
CODE
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class jump : MonoBehaviour {
private Rigidbody rb;
private float initialPos = 0.5f ;
// Use this for initialization
void Start () {
rb = GetComponent<Rigidbody>();
}
// Update is called once per frame
void Update () {
//Debug.Log(rb.velocity.magnitude);
if (Input.GetKeyDown(KeyCode.Space))
{
rb.velocity = new Vector3(0f , 1f , 0f) * 10 ;
Debug.Log(rb.velocity);
}
if (rb.velocity.y > 0 && !Input.GetKey(KeyCode.Space))
{
float dis = rb.transform.position.y - initialPos;
Debug.Log(dis);
rb.velocity += new Vector3(0f, 1f, 0f) * Physics.gravity.y;
//Debug.Log(rb.velocity);
//Debug.Log("I am here");
//rb.velocity = Vector3.zero;
}
}
private void OnCollisionEnter(Collision collision)
{
rb.velocity = Vector3.zero;
Debug.Log(rb.velocity);
Debug.Log("...........................Collision " + gameObject.name);
}
}
Related
Hi im new to programming in C# and i ran into a problem.Eveything is working,only the value wont return to 0 when the button is not pressed,i can change the direction of the movement,but the object wont stop moving...Here is the code!
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Movement : MonoBehaviour
{
private Rigidbody2D rb2D;
private float speed = 1f;
private float moveHorizontal;
void Start()
{
rb2D = GetComponent<Rigidbody2D>();
}
void Update()
{
moveHorizontal = Input.GetAxisRaw("Horizontal");
}
void FixedUpdate()
{
if (moveHorizontal > 0.1f || moveHorizontal < -0.1f)
{
rb2D.AddForce(new Vector2 (moveHorizontal * speed, 0f), ForceMode2D.Impulse);
}
}
}
I see you adding forces, but you never reset the velocity to 0 anywhere
you could do this like e.g.
if(Mathf.Abs(moveHorizontal) > 0.1f)
{
...
}
else
{
var vel = rb2D.velocity;
vel.x = 0;
rb2D.velocity = vel;
}
GOAL
So I'm creating a top down arena battler type game, and I want you to be able to restart the game by pressing R.
PROBLEM
When I press R, the whole scene resets as it should, except all the enemies that were previously instantiated (and then destroyed) are spawned again, all at once.
CODE
This is the enemy spawning code :
using System.Collections.Generic;
using UnityEngine;
public class EnemySpawn : MonoBehaviour
{
private float nextActionTime = 0.0f;
public float period = 5f;
public GameObject enemy;
void Update()
{
if (Time.time > nextActionTime ) {
nextActionTime += period;
GameObject clone = Instantiate(enemy, new Vector3(-1, 3, 0), Quaternion.identity);
clone.tag = "enemy";
}
}
}
This is the player code, responsible for restarting the scene (I have marked what I belive to be the relevantant sections with dashes) :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class PlayerController : MonoBehaviour
{
public Rigidbody2D rb;
public GameObject Shield;
public GameObject ShieldInstance;
public float moveSpeed = 4.3f;
public float sheildSpeed = 5f;
Vector2 movement;
AudioSource woop;
AudioSource waa;
----------------------------
GameObject[] enemies;
----------------------------
bool isDead = false;
void Start() {
woop = GameObject.Find("Main Camera/ShieldSFX").GetComponent<AudioSource>();
waa = GameObject.Find("Main Camera/DefeatSFX").GetComponent<AudioSource>();
}
void Update()
{
--------------------------------------------------------------
enemies = GameObject.FindGameObjectsWithTag("enemy");
--------------------------------------------------------------
movement.x = Input.GetAxisRaw("Horizontal");
movement.y = Input.GetAxisRaw("Vertical");
Vector3 mouseScreen = Input.mousePosition;
Vector3 mouse = Camera.main.ScreenToWorldPoint(mouseScreen);
transform.rotation = Quaternion.Euler(0, 0, Mathf.Atan2(mouse.y - transform.position.y, mouse.x - transform.position.x) * Mathf.Rad2Deg - 90);
if (Input.GetMouseButtonDown(0))
{
if (ShieldInstance != null || transform.GetChild(0).GetComponent<SpriteRenderer>().enabled == false) { return; }
woop.Play();
ShieldInstance = Instantiate(Shield, transform.position + transform.forward + transform.up, transform.rotation);
ShieldInstance.transform.parent = transform;
}
if (Input.GetMouseButtonUp(0))
{
if (ShieldInstance == null) { return; }
ShieldInstance.transform.parent = null;
ShieldInstance.GetComponent<ShieldController>().LaunchForward(sheildSpeed);
Destroy(ShieldInstance, 2.3f);
}
-------------------------------------------------------------------------------
if (Input.GetKey("r")) {
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
foreach (GameObject one in enemies) {
Destroy(one);
}
}
-------------------------------------------------------------------------------
}
void FixedUpdate() {
if (!isDead) {
rb.MovePosition(rb.position + movement * moveSpeed * Time.fixedDeltaTime);
}
}
void OnCollisionEnter2D(Collision2D other) {
if (other.gameObject.tag == "enemy") {
waa.Play();
GameObject.Find("Canvas/gameover").GetComponent<Text>().enabled = true;
transform.GetChild(0).GetComponent<SpriteRenderer>().enabled = false;
GetComponent<PolygonCollider2D>().enabled = false;
}
}
}
And this is the enemy code :
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyFollow : MonoBehaviour
{
public float moveSpeed;
public ParticleSystem explode;
AudioSource boom;
Vector2 movement;
GameObject player;
Rigidbody2D rb;
SpriteRenderer sr;
PolygonCollider2D pc;
void Start() {
rb = GetComponent<Rigidbody2D>();
sr = transform.GetChild(0).GetComponent<SpriteRenderer>();
pc = GetComponent<PolygonCollider2D>();
player = GameObject.Find("Player");
boom = GameObject.Find("Main Camera/ExplodeSFX").GetComponent<AudioSource>();
}
void Update()
{
Vector2 difference = (player.transform.position - new Vector3(2, .5f, 0)) - transform.position;
if (difference.x > 0) {
movement.x = 1;
} else if (difference.x < 0){
movement.x = -1;
} else {
movement.x = 0;
}
if (difference.y > 0) {
movement.y = 1;
} else if (difference.y < 0){
movement.y = -1;
} else {
movement.y = 0;
}
rb.MovePosition(rb.position + movement * moveSpeed * Time.fixedDeltaTime);
}
void OnCollisionEnter2D(Collision2D other) {
if (other.gameObject.tag == "shield") {
StartCoroutine(ExplodeF());
}
}
private IEnumerator ExplodeF() {
explode.Play();
boom.Play();
sr.enabled = false;
pc.enabled = false;
yield return new WaitForSeconds(explode.main.startLifetime.constantMax);
Destroy(gameObject);
}
}
I would really appreciate any help!
If you want / need more details, just leave a comment :)
The problem is in Time.time, it is time since the start of the application, not since the start of the scene. So if you were in the game 30 secs, Time.time is 30 secs. If you reload the scene it is still 30 secs.
You have to count the time passed since entering the scene. Then it won't respawn all the enemies on scene reload.
When you restart the scene, everything is being destroyed and reset back except for the time.
The problem in your code is in the enemy spawner. Time.time returns the time passed since you started the game (and not since the scene was loaded). So, after the restart the if condition is true and the enemies are spawned.
If you want to count the time (in seconds) since the scene was loaded, what you can do is to add a variable in the enemy spawner class that would count the time
using System.Collections.Generic;
using UnityEngine;
public class EnemySpawn : MonoBehaviour
{
private float nextActionTime = 0.0f;
private float timeSinceStart = 0;
public float period = 5f;
public GameObject enemy;
void Update()
{
if (timeSinceStart > nextActionTime ) {
nextActionTime += period;
GameObject clone = Instantiate(enemy, new Vector3(-1, 3, 0), Quaternion.identity);
clone.tag = "enemy";
}
timeSinceStart += Time.deltaTime;
}
}
See Time.deltaTime
I am attempting to make 2D topdown shooter game. I first implemented weapon rotation and it worked fine. However, after implementing character sprite flip, the weapon sprite now doesn't rotate to right and the character sprite went weird. What am I doing wrong?
Character Movement Script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Movement : MonoBehaviour
{
public float speed;
private Rigidbody2D rb;
Vector2 movement;
bool facingRight = true;
// Update is called once per frame
private void Awake()
{
rb = GetComponent<Rigidbody2D>();
}
void Update()
{
movement.x = Input.GetAxisRaw("Horizontal");
movement.y = Input.GetAxisRaw("Vertical");
Vector3 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
if (mousePos.x > transform.position.x && facingRight)
{
flip();
}
else if (mousePos.x > transform.position.x && !facingRight)
{
flip();
}
}
void flip()
{
facingRight = !facingRight;
transform.Rotate(0f, 180f, 0f);
}
private void FixedUpdate()
{
movement.Normalize();
rb.velocity = new Vector2(movement.x * speed * Time.fixedDeltaTime, movement.y * speed * Time.fixedDeltaTime);
}
}
Weapon Rotation Script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GunRotation : MonoBehaviour
{
// Gun Rotation Function
public float offset;
private SpriteRenderer spriteRender;
// Start is called before the first frame update
void Start()
{
spriteRender = GetComponent<SpriteRenderer>();
}
// Update is called once per frame
void Update()
{
// Gun Rotation Function
Vector3 difference = Camera.main.ScreenToWorldPoint(Input.mousePosition) - transform.position;
float rotZ = Mathf.Atan2(difference.y, difference.x) * Mathf.Rad2Deg;
transform.rotation = Quaternion.Euler(0f, 0f, rotZ + offset);
if (rotZ < 89 && rotZ > -89)
{
Debug.Log("Facing right");
spriteRender.flipY = false;
}
else
{
Debug.Log("Facing left");
spriteRender.flipY = true;
}
}
}
You need just to reverse > in else if condition and it'll work fine
Vector3 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
if (mousePos.x > transform.position.x && !facingRight)
{
flip();
}
else if (mousePos.x < transform.position.x && facingRight)
{
flip();
}
I want my player not to rotate anymore after the game starts. I freeze rotation in the script and in the constraints too , but the player still rotates when it moves forward . What can I do ? ( I have a fps , and a character controller) . I also have a canvas with buttons to control left , right ? Should I put the rigibody or player script inside the Character object ( I made a player game object that contains the character and the camera)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class Player : MonoBehaviour
{
public float playerSpeed = 1500;
public float directionalSpeed = 20;
private Rigidbody rb;
// Start is called before the first frame update
void Start()
{
GetComponent<Rigidbody>().constraints = RigidbodyConstraints.FreezeRotation;
}
// Update is called once per frame
void Update()
{
#if UNITY_EDITOR || UNITY_STANDALONE || UNITY_WEBPLAYER
float moveHorizontal = Input.GetAxis("Horizontal");
transform.position = Vector3.Lerp(gameObject.transform.position, new Vector3(Mathf.Clamp(gameObject.transform.position.x + moveHorizontal, -2.5f, 2.5f), gameObject.transform.position.y, gameObject.transform.position.z), directionalSpeed * Time.deltaTime);
#endif
GetComponent<Rigidbody>().velocity = Vector3.forward * playerSpeed * Time.deltaTime;
transform.Rotate(Vector3.right * GetComponent<Rigidbody>().velocity.z / 3);
//MOBILE CONTROLS
Vector2 touch = Camera.main.ScreenToWorldPoint(Input.mousePosition + new Vector3(0, 0, 10f));
if (Input.touchCount > 0)
{
transform.position = new Vector3(touch.x, transform.position.y, transform.position.z);
}
}
public void MoveLeft()
{
rb.velocity = new Vector2(-playerSpeed, rb.velocity.y);
}
public void MoveRight ()
{
rb.velocity = new Vector2(playerSpeed, rb.velocity.y);
}
public void StopMoving()
{
rb.velocity = new Vector2(0f, rb.velocity.y);
}
void DetectInput()
{
float x = Input.GetAxisRaw("Horizontal");
if (x > 0 )
{
MoveRight();
}
else if ( x < 0)
{
MoveLeft();
}
else
{
StopMoving();
}
}
}
If you added a rigidbody you can freeze the position or rotation
(no matter if rigidbody is 2d or no)
For first you have to declare the rigidbody
rb = GetComponent<Rigidbody>();
And then you can freeze your rotation RigidbodyConstraints (the selected label in the screenshot)
rigidbody.constraints = RigidbodyConstraints.FreezeRotationX;
//freeze only one rotation
rigidbody.constraints = RigidbodyConstraints.FreezePositionX | RigidbodyConstraints.FreezePositionZ | RigidbodyConstraints.FreezePositionY;
//freeze all rotations
to uncheck just type
rigidbody.constraints = RigidbodyConstraints.None;
If your game is 2d just add 2d to all Rigidbodies texts
Rotate using MoveRotation
Using the Rigidbody component constraints will only constrain the game object through the physics engine. You are currently rotating the transform manually.
From documentation:
void FixedUpdate()
{
Quaternion deltaRotation = Quaternion.Euler(m_EulerAngleVelocity * Time.deltaTime);
m_Rigidbody.MoveRotation(m_Rigidbody.rotation * deltaRotation);
}
I am just starting out with unity and am also making a game for a school project. My 2d game character can do the walk animation when I press the "a" and "d" keys and the sprite flips, but it stays in the same position. Below is my PlayerController script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
private float speed = 3f;
private Animator anim;
private SpriteRenderer sr;
// Start is called before the first frame update
void Awake()
{
anim = GetComponent<Animator>();
sr = GetComponent<SpriteRenderer>();
}
// Update is called once per frame
void Update()
{
Move();
}
void Move()
{
float h = Input.GetAxisRaw("Horizontal");
Vector3 temp = transform.position;
if (h > 0)
{
temp.x += speed * Time.deltaTime;
sr.flipX = true;
anim.SetBool("Walk", true);
}
else if (h < 0)
{
temp.x -= speed * Time.deltaTime;
sr.flipX = false;
anim.SetBool("Walk", true);
}
else if (h == 0)
{
anim.SetBool("Walk", false);
}
}
}
You're setting 'temp' to equal transform.position, but that doesn't mean that transform.position equals 'temp'. Here, the below script should give you what you want
using UnityEngine;
public class PlayerController : MonoBehaviour
{
private float speed = 3f;
private Animator anim;
private SpriteRenderer sr;
void Awake()
{
anim = GetComponent<Animator>();
sr = GetComponent<SpriteRenderer>();
}
void Update()
{
Move();
}
void Move()
{
float h = Input.GetAxisRaw("Horizontal");
transform.Translate(Vector2.right * (h * speed * Time.deltaTime));
anim.SetBool("Walk", h != 0f);
if (anim.GetBool("Walk"))
Flip(h > 0f);
}
void Flip(bool facingRight)
{
sr.flipX = !facingRight;
}
}