I am extremely close to finishing my game, every code I posted works well but I want my player to die whether it collides with the box (which is the enemy). However, I've tried to do some research and I can't seem to find the solution. How do I do this? Here's the code for the Player (JugadorScript.cs):
using UnityEngine;
using System.Collections;
public class JugadorScript : MonoBehaviour
{
public float velocidad = -10f;
void Start()
{
}
// Update is called once per frame
void Update()
{
}
public void moverIzquierda()
{
transform.Translate(Vector2.right * velocidad * Time.deltaTime);
transform.eulerAngles = new Vector2(0, 0);
}
public void moverDerecha()
{
transform.Translate(Vector2.right * velocidad * Time.deltaTime);
transform.eulerAngles = new Vector2(0, 180);
}
}
The EnemySpawner.cs code, which works excellent:
using UnityEngine;
using System.Collections;
using System;
public class EnemySpawner : MonoBehaviour
{
public GameObject BlockPrefab;
float maxSpawnRateInSeconds = 2.5f;
void Start()
{
Invoke("SpawnEnemy", maxSpawnRateInSeconds);
InvokeRepeating("IncreaseSpawnRate", 0f, 30f);
}
// Update is called once per frame
void Update()
{
}
void SpawnEnemy()
{
Vector2 min = Camera.main.ViewportToWorldPoint(new Vector2(0, 0));
Vector2 max = Camera.main.ViewportToWorldPoint(new Vector2(1, 1));
GameObject anEnemy = (GameObject)Instantiate(BlockPrefab);
anEnemy.transform.position = new Vector2(UnityEngine.Random.Range(min.x, max.x), max.y);
ScheduleNextEnemySpawn();
}
void ScheduleNextEnemySpawn()
{
float spawnInNSeconds;
if (maxSpawnRateInSeconds > 1f)
{
spawnInNSeconds = UnityEngine.Random.Range(1f, maxSpawnRateInSeconds);
}
else
spawnInNSeconds = 1f;
Invoke("SpawnEnemy", spawnInNSeconds);
}
void IncreaseSpawnRate()
{
if (maxSpawnRateInSeconds > 1f)
maxSpawnRateInSeconds--;
if (maxSpawnRateInSeconds == 1f)
CancelInvoke("IncreaseSpawnRate");
}
}
And the BlockScript.cs, which is my enemy script:
using UnityEngine;
using System.Collections;
public class BlockScript : MonoBehaviour
{
private GameObject wayPoint;
private Vector3 wayPointPos;
private Rigidbody2D rigidBody2D;
public bool inGround = true;
private float jumpForce = 400f;
private float speed = 6.0f;
void Start()
{
wayPoint = GameObject.Find("wayPoint");
}
private void awake()
{
rigidBody2D = GetComponent<Rigidbody2D>();
}
void Update()
{
if (inGround)
{
inGround = false;
rigidBody2D.AddForce(new Vector2(0f, jumpForce));
}
wayPointPos = new Vector3(wayPoint.transform.position.x, transform.position.y,
wayPoint.transform.position.z);
transform.position = Vector3.MoveTowards(transform.position,
wayPointPos, speed * Time.deltaTime);
Vector2 min = Camera.main.ViewportToWorldPoint(new Vector2(0, 0));
if (transform.position.y < min.y)
{
Destroy(gameObject);
}
}
}
As you can see in the doc, the function you are looking for is OnCollisionEnter.
Check this tutorial:
https://unity3d.com/es/learn/tutorials/topics/physics/detecting-collisions-oncollisionenter
Related
I have an enemy prefab with and a bullet prefab with rigidbody2D and boxcolliders to both of them. I have made a TakeDamage function for the enemy when i made meelee combat and also a bullet shooting script. I made a simple OnCollisionEnter2D on the enemy(code is below) and they do collide and give the collision effect but the function doesn't work, it doesn't give any errors either... What do I do now?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class enemy : MonoBehaviour
{
public Transform player;
private Rigidbody2D rb;
[SerializeField] private SpriteRenderer sr;
private Vector2 movement;
public float moveSpeed = 5f;
public int maxHealth = 100;
int currentHealth;
Color32 colorRes = new Color32(255, 100, 50, 255);
public ParticleSystem deathParticles;
public GameObject projectile;
public int enemyDamage = 50;
public LayerMask rock;
// Start is called before the first frame update
void Start()
{
rb = this.GetComponent<Rigidbody2D>();
sr = GetComponent<SpriteRenderer>();
currentHealth = maxHealth;
}
// Update is called once per frame
void Update()
{
sr.flipX = player.position.x - transform.position.x > 0;
Vector3 direction = player.position - transform.position;
direction.Normalize();
movement = direction;
}
private void FixedUpdate()
{
moveCharacter(movement);
}
void moveCharacter(Vector2 direction)
{
rb.MovePosition((Vector2)transform.position + (direction * moveSpeed));
}
public void TakeDamage()
{
currentHealth -= enemyDamage;
if(currentHealth <= 0)
{
Die();
}
StartCoroutine(BecomeRed());
}
void Die()
{
Instantiate(deathParticles, transform.position, Quaternion.identity);
Destroy(gameObject);
}
IEnumerator BecomeRed()
{
sr.color = colorRes;
yield return new WaitForSeconds(0.6f);
sr.color = Color.white;
}
void OnCollisionEnter2D(Collision2D coll)
{
Debug.Log("test");
if (coll.gameObject.name == "rock")
{
TakeDamage();
Destroy(projectile);
}
}
}
I Am trying to add a swinging system to my game but whenever my player does the swinging animation it goes back to the same place how would I fix something like that? here is a video showing what it does: https://streamable.com/7jxgqx
I Use a character controller to move the player so does anyone know how to prevent the player from snapping back to the place it came from
Problem: https://streamable.com/7jxgqx
my codes: 1)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Swinging : MonoBehaviour
{
[SerializeField]Animator m_Animator;
CharacterController cc;
[SerializeField]GameObject jumpArea;
PlayerController playerController;
private void Start()
{
cc = GetComponent<CharacterController>();
playerController = GetComponent<PlayerController>();
playerController.enabled = true;
cc.enabled = true;
}
private void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Collider"))
{
StartCoroutine(StartSwinging());
}
}
IEnumerator StartSwinging()
{
m_Animator.SetTrigger("swing");
cc.enabled = false;
playerController.enabled = false;
yield return new WaitForSeconds(2.3f);
m_Animator.SetBool("afterSwing", true);
Destroy(jumpArea);
playerController.enabled = true;
cc.enabled = true;
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
CharacterController cc;
public Transform groundCheck;
public LayerMask groundLayer;
float wallJumpVelocity;
public Animator m_Animator;
private Vector3 direction;
public float speed = 5f;
public float jumpForce = 8f;
public float gravity = -20f;
public bool canDoubleJump = true;
public bool isGrounded;
void Start()
{
cc = GetComponent<CharacterController>();
}
// Update is called once per frame
void Update()
{
float horizontalInput = Input.GetAxis("Horizontal");
direction.x = horizontalInput * speed;
m_Animator.SetFloat("run", Mathf.Abs(horizontalInput)); // Mathf.Abs i igivea rac modulebi anu |-5| = 5
isGrounded = Physics.CheckSphere(groundCheck.position, 0.2f, groundLayer);
m_Animator.SetBool("isGrounded", isGrounded);
Jump();
if (horizontalInput != 0)
{
Quaternion flip = Quaternion.LookRotation(new Vector3(0, 0, horizontalInput));
transform.rotation = flip;
}
cc.Move(direction * Time.deltaTime);
}
void Jump()
{
// es kodi anichebs chvens motamashes axtomis funqicas
if (isGrounded)
{
canDoubleJump = true;
if (Input.GetButtonDown("Jump"))
{
direction.y = jumpForce;
}
}
else
{
if (canDoubleJump && Input.GetButtonDown("Jump"))
{
m_Animator.SetTrigger("doubleJump");
direction.y = jumpForce;
canDoubleJump = false;
}
}
direction.y += gravity * Time.deltaTime;
}
}
I Tried applying root motion too but it did not work i am using animations from mixamo.
Thanks <3
I'm new to unity and I'm trying to make an isometric 3d game, but I have some problem, I would like that the player stops moving when I stop using the virtual joystick. Here's my 2 scripts for movement. The first one is in the virtual joystick to make it move and the second one is in the player and make it move in the direction of the joystick.
Joystick script:
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System.Collections;
public class VirtualJoystick : MonoBehaviour, IDragHandler, IPointerUpHandler, IPointerDownHandler
{
private Image bgImg;
private Image joystickImg;
private Vector3 inputVector;
private void Start()
{
bgImg = GetComponent<Image>();
joystickImg = transform.GetChild(0).GetComponent<Image>();
}
public virtual void OnDrag(PointerEventData ped)
{
Vector2 pos;
if (RectTransformUtility.ScreenPointToLocalPointInRectangle(bgImg.rectTransform, ped.position, ped.pressEventCamera, out pos))
{
pos.x = (pos.x / bgImg.rectTransform.sizeDelta.x);
pos.y = (pos.y / bgImg.rectTransform.sizeDelta.x);
inputVector = new Vector3(pos.x * 2 + 1, 0, pos.y * 2 - 1);
inputVector = (inputVector.magnitude > 1.0f) ? inputVector.normalized : inputVector;
// Move joystickImg
joystickImg.rectTransform.anchoredPosition =
new Vector3(inputVector.x * bgImg.rectTransform.sizeDelta.x / 3
, inputVector.z * (bgImg.rectTransform.sizeDelta.y / 3));
}
}
public virtual void OnPointerDown(PointerEventData ped)
{
OnDrag(ped);
}
public virtual void OnPointerUp(PointerEventData ped)
{
inputVector = Vector3.zero;
joystickImg.rectTransform.anchoredPosition = Vector3.zero;
}
public float Horizontal()
{
if (inputVector.x != 0)
return inputVector.x;
else
return Input.GetAxis("Horizontal");
}
public float Vertical()
{
if (inputVector.x != 0)
return inputVector.z;
else
return Input.GetAxis("Vertical");
}
}
Player Script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Move : MonoBehaviour
{
public float moveSpeed = 20f;
public VirtualJoystick moveJoystick;
private void Update()
{
Vector3 dir = Vector3.zero;
dir.x = moveJoystick.Horizontal();
dir.z = moveJoystick.Vertical();
GetComponent<Rigidbody>().AddForce(dir * moveSpeed);
}
}
For stopping the player when you let go of the virtual joystick, we can tell the player's rigidbody to sleep. This will make the player halt until another force is added to it.
Update your Player script to the following:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Move : MonoBehaviour
{
public float moveSpeed = 20f;
public VirtualJoystick moveJoystick;
public Rigidbody rb;
private Vector3 dir = Vector3.zero;
private bool wasMoving = false;
private void Update()
{
dir.x = moveJoystick.Horizontal();
dir.z = moveJoystick.Vertical();
if (dir.magnitude > 0)
{
wasMoving = true;
}
}
private void FixedUpdate()
{
if (wasMoving && dir.magnitude == 0f)
{
wasMoving = false;
rb.Sleep();
}
rb.AddForce(dir * moveSpeed);
}
}
It's also a good idea to store the Rigidbody as a variable so you don't recompute it every update. Be sure to drag it into the script from the inspector.
I am following a Unity tutorial (https://www.youtube.com/watch?v=BrlJsdP-VGo).
The problem I am having is whenever I instantiate the shot my player gameobject is firing, there is quite a long delay (about 1 sec) before it starts moving.
Here is my code:
Player gameobject:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player_Controller : MonoBehaviour
{
public GameObject bolt;
public float fireRate;
private Rigidbody rb;
private int speed = 10;
private float nextFire;
private void Awake()
{
rb = GetComponent<Rigidbody>();
}
void FixedUpdate ()
{
float mh = Input.GetAxis("Horizontal"), mv = Input.GetAxis("Vertical");
Vector3 move = new Vector3(mh, 0f, mv);
rb.velocity = move * speed;
rb.position = new Vector3(Mathf.Clamp(rb.position.x, -6, 6), 0f, Mathf.Clamp(rb.position.z, -4, 8));
rb.rotation = Quaternion.Euler(0, 0, rb.velocity.x * -5);
}
private void Update()
{
if (Input.GetKey("space") && Time.time > nextFire)
{
nextFire = Time.time + fireRate;
Instantiate(bolt, new Vector3(transform.position.x, 0,
transform.position.z + 1.25f), transform.rotation);
}
}
}
Shot that is being fired:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Bolt_Mover : MonoBehaviour
{
Rigidbody rb;
public float speed;
private void Awake()
{
rb = GetComponent<Rigidbody>();
}
private void Start()
{
rb.velocity = transform.forward * speed;
}
}
How can I edit the c# code to show that player 1 or 2 won when the other player dies. And show the dead player that they lost?
PlayerController Script
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
namespace S3
{
public class PlayerController : NetworkBehaviour {
public GameObject bulletPrefab;
public Transform bulletSpawn;
// Update is called once per frame
void Update ()
{
if (!isLocalPlayer) {
return;
}
float x = Input.GetAxis ("Horizontal") * Time.deltaTime * 150.0f;
float z = Input.GetAxis ("Vertical") * Time.deltaTime * 3.0f;
transform.Rotate (0, x, 0);
transform.Translate (0, 0, z);
if (Input.GetKeyDown (KeyCode.Space))
{
CmdFire();
}
}
[Command]
void CmdFire()
{
GameObject bullet = (GameObject) Instantiate(bulletPrefab, bulletSpawn.position, bulletSpawn.rotation);
bullet.GetComponent<Rigidbody> ().velocity = bullet.transform.forward * 6.0f;
NetworkServer.Spawn(bullet);
Destroy (bullet, 2);
}
public override void OnStartLocalPlayer()
{
GetComponent<MeshRenderer> ().material.color = Color.blue;
}
}
}
Health Script
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Networking;
namespace S3
{
public class Health : NetworkBehaviour {
public const int maxHealth = 100;
[SyncVar (hook = "OnChangeHealth")]public int currentHealth = maxHealth;
public RectTransform healthbar;
public void TakeDamage(int amount)
{
if (!isServer)
{
return;
}
currentHealth -= amount;
if (currentHealth <= 0)
{
currentHealth = maxHealth;
RpcRespawn();
}
}
void OnChangeHealth(int health)
{
healthbar.sizeDelta = new Vector2(health * 2, healthbar.sizeDelta.y);
}
[ClientRpc]
void RpcRespawn()
{
if(isLocalPlayer)
{
transform.position = Vector3.zero;
}
}
}
}
This is the codeaspğlasdlişsadlşisadlşiadsilşdslaişdlasişlişdsacdl işsadilşaLDİŞaslişÖDASİÖŞLDÖİLSAŞDöliasödilascöildaiölşsdöiaşsdöilasödilasiöldasöildasöildöilasdöilaöildöildasöildaöilsdöilasdölasdöliasölidasöildsaöildsöiladiösladöilsadöilsadöilasdiölsadiölsaöidlsaöildsöidiösladiölsadiölsadöilasöild
You can send a Command to the server with netID of the player who have won and check in RPC if the netID matches.
If netID matches for the local player then, he is the winner. Otherwise, he loses. Haven't tested the code below but should work:
[Command]
public void CmdGameWon()
{
RpcGameEnd(this.netId);
}
[ClientRpc]
public void RpcGameEnd(NetworkInstanceId nid)
{
if(this.isLocalPlayer && this.netId==nid){
//Process win here
}else{
//Process lose here
}
}