As I was trying to make a game in which player kick the ball when the player collides with ball and as I press Q but it is not working and not showing any error
public Rigidbody rg;
void OnCollisionEnter(Collision col)
{
if(col.gameObject.name=="ball")
{
if(Input.GetKeyDown(KeyCode.Q))
{
rg.AddForce(100,0,0);
}
}
}
Potentially try to add another sphere collider to the ball, and make that a trigger
then it is a matter of changing :
public Rigidbody rg;
void OnCollisionEnter(Collision col)
{
if(col.gameObject.name=="ball")
{
if(Input.GetKeyDown(KeyCode.Q))
{
rg.AddForce(100,0,0);
}
}
}
To :
public Rigidbody rg;
void OnTriggerEnter(Collision col)
{
if(col.gameObject.name=="ball")
{
if(Input.GetKeyDown(KeyCode.Q))
{
rg.AddForce(100,0,0);
}
}
}
The idea is that collision in unity is finicky, so your best bet is just to have a larger trigger to detect if the player is within range of the ball
Side NOTE :
I'm guessing that this is on your player, so maybe you could try this as well :
keep in mind that the "if" statement is just in case the ball object has different
name extensions, or maybe "ball (clone)" etc.
Rigidbody rb;
void Start(){
rb = gameObject.GetComponent<Rigidbody>();
}
void OnTriggerEnter(Collision col){
if(col.gameObject.name.ToString().Contains("ball") &&
Input.GetkeyDown(KeyCode.Q))
{
//here you can add force to the player, or to the ball
// for the player :
rb.AddForce(100,0,0);
// for the ball
col.GetComponent<Rigidbody>().AddForce(100,0,0);
}
}
This should give you a step in a different direction, Hopefully, this helps!
Cheers!
Related
I am wokring on a game where a player has to go through an enemy to score a point. But I am struggling to make the score count work. I am watching tutorials and trying various ways but something isnt working so I hope someone can help me here.
I have a player prefab, which gets instantiated when I press play in Unity. Then I have enemies spawning and when a player goes though one, the score should go to 1..and so on.
I have a gameObject in the scene with score script attached
public class Score : MonoBehaviour
{
public Text scoreText;
int score;
// Start is called before the first frame update
void Start()
{
score = 0;
}
public void ScoreUp()
{
score++;
scoreText.text = score.ToString();
}
}
Then I have a player script attached to a player prefab
public class PlayerController : MonoBehaviour
{
private Score score; //Reference to Score script
private void Start()
{
score = GameObject.FindWithTag("ReferenceManager").GetComponent<Score>();
}
private void Update()
{
if (Input.GetMouseButtonDown(0))
{
//movement code
}
}
public void OnTriggerEnter2D(Collider2D collision)
{
if (collision.CompareTag("Enemy"))
{
score.ScoreUp();
Debug.Log("HIT");
}
}
}
Reference manager tag is the gameObject in the scene with score script.
If someone could help me with this problem would be really awesome. Thank you
Define a gameobject variable so you can attach the score object to it in the editor
public class PlayerController : MonoBehaviour
{
[SerializeField]
public GameObject score_object;//This will allow u to select the player controller game object and set the variable to the score game object. The score game object is where the data will be stored.
private Score score;
private void Start()
{
score = score_object.GetComponent<Score>();
}
private void Update()
{
if (Input.GetMouseButtonDown(0))
{
//movement code
}
}
public void OnTriggerEnter2D(Collider2D collision)
{
if (collision.CompareTag("Enemy"))
{
score.ScoreUp();
Debug.Log("HIT");
}
}
}
I have never tried using the tag manager, What i suspect is that may be where your problem lies. Just try instancing it like this and see what happens.
Apparently my score collider which is attached to enemy doesnt work.
I tried the same thing but with trigger collider on its own and the score count works perfectly. So I will play around and try to figure out the correct place for that trigger collider. Thank you whoever tried to help me! :)
UPDATE:
I had two scripts attached to scoreManager, and when i removed the other script, the score count started to work. Actually not sure why 2 scripts were conflicting but this fixed the problem.
I was trying to find the answer for the last 3 hours and I couldn't find anything that would help me. It shows that the camera already has constraints when it enters the cube, so it works, but it doesn't because it's not freezing the camera. I don't know what to do already.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LCOE : MonoBehaviour
{
public GameObject cam;
Rigidbody rig;
private void OnTriggerEnter(Collider other)
{
if (other.tag == "Player")
{
cam.GetComponent<Rigidbody>().constraints = RigidbodyConstraints.FreezeAll;
}
}
private void OnTriggerExit(Collider other)
{
if (other.tag == "Player")
{
cam.GetComponent<Rigidbody>().constraints = RigidbodyConstraints.None;
}
}
}
Changing constrains or isKinematic on Rigidbody will only disable physics movement, but it will still move together with parent object. Your camera should not be child of player and script attached to camera should look like that:
class MyCamera : MonoBehaviour{
public Transform target;
public Vector3 offset;
public bool isMovementDisabled;
void LateUpdate(){
if(isMovementDisabled)
return;
transform.position = target.position + offset;
}
}
Or use cinemachine
When my Player (GameObject) meets Lava, they should respawn in a specific scene.
This is the code I have assigned to the Player:
void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag == "Lava")
{
GameObject.Find("Controller").GetComponent<Controller>().Respawn();
}
}
Controller is a GameObject, that I don't want to Destroy by Changing level, so this is the code for my Controller GameObject:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class Controller : MonoBehaviour
{
private static bool created = false;
public static Controller instance;
GameObject Player;
Vector3 respawnPoint;
void Awake()
{
if (instance = null)
{
instance = this;
}
else
{
Destroy(this.gameObject);
return;
}
if (!created)
{
DontDestroyOnLoad(this.gameObject);
created = true;
Player = GameObject.Find("Player");
respawnPoint = GameObject.Find("RespawnPoint").transform.position;
}
}
public void Respawn()
{
SceneManager.LoadScene(0);
Player.transform.position = respawnPoint;
}
}
RespawnPoint is just an invisible Cube GameObject, where I want the player to respawn.
Let's say the Game Starts with Scene "0" (this is where the RespawnPoint is, too.)
Then the Player goes to Scene "1" and dies (meets Lava). Then I want the Game to change back to Scene "0" and teleport the Player to the RespawnPoint.
The Scene-Change works good, but the player always starts at the same position, where he starts the first time and he's not teleported to the RespawnPoint.
What am I doing wrong?!
First of all you lack the "==" in the first 'if' from the Awake: if (instance == null
The code is fine or it does seem so to me, but the RespawnPoint should be in the Scene your Player meets the lava not in the Scene you are loading. If not the starting position of the player will always be (0,0,0).
I would recommend coming to this in a completely different way. I would make a public Transform[] Spawnpoints. Since the transform is public you can assign different objects to it. Make an empty game object and position it where you want to spawn. Then use
Void OnTriggerEnter(collider2D, other){
if(other.gameObject.tag == lava) {
transform.position = spawnpoints[0].position;
}
}
In the inspector set the Transform to be a size of 1 and set the respawn GameObject as the one transform.
Thanks to your answers, they helped me solving this problem.
I added a "DontDestroyOnLoad" to the RespawnPoint and than i changed the Controller Code to this:
{
private static bool created = false;
public static Controller instance;
void Awake()
{
if (instance == null)
{
instance = this;
}
else
{
Destroy(this.gameObject);
return;
}
if (!created)
{
DontDestroyOnLoad(this.gameObject);
created = true;
}
}
public void Respawn()
{
SceneManager.LoadScene(0);
GameObject.Find("Player").transform.position = GameObject.Find("RespawnPoint").transform.position;
}
}
now the player gets teleported to the correct RespawnPoint. Thanks for your help!
I made a Project in Unity, a game to be clear. So the player has a Sci-fi car and he tries to avoid obstacles-rocks.
When the car hits a rock, the Game Manager load the "credits" screen to choose between quit or restart.
My problem is that I want to make the rock explode when the car goes on it and then the Game Manager will load the "credits" screen.
Some of my code:
For player collision:
public class PlayerCollision : MonoBehaviour {
public PlayerMovement movement;
public static bool y = true;
public void OnCollisionEnter (Collision collisionInfo)
{
// We check if the object we collided with has a tag called "Obstacle".
if (collisionInfo.collider.tag == "Obstacle")
{
movement.enabled = false; // Disable the players movement.
y = false;
FindObjectOfType<GameManager>().EndGame();
}
}
}
Game Manager:
public class GameManager : MonoBehaviour {
bool gameHasEnded = false;
public float restartDelay = 1f;
public GameObject completeLevelUI;
public void CompleteLevel ()
{
completeLevelUI.SetActive(true);
}
public void EndGame ()
{
if (gameHasEnded == false)
{
gameHasEnded = true;
Debug.Log("GAME OVER");
Invoke("Restart", restartDelay);
}
}
void Restart ()
{
SceneManager.LoadScene("Credits");
//SceneManager.LoadScene(SceneManager.GetActiveScene().name);
}
}
The endTrigger:
public class EndTrigger : MonoBehaviour {
public GameManager gameManager;
void OnTriggerEnter ()
{
gameManager.CompleteLevel();
}
}
LevelComplete:
public class LevelComplete : MonoBehaviour {
public void LoadNextLevel ()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex + 1);
}
}
Menu:
public class Menu : MonoBehaviour {
public void StartGame ()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex + 1);
}
}
I have written other scripts. If you want anything let me know. Thanks guys.
Add a particle system to your rocks. Uncheck "looping" and "play on awake". Then you can play by adding the line below.
public void OnCollisionEnter (Collision collisionInfo)
{
// We check if the object we collided with has a tag called "Obstacle".
if (collisionInfo.collider.tag == "Obstacle")
{
movement.enabled = false; // Disable the players movement.
y = false;
collisionInfo.gameObject.GetComponent<ParticleSystem>().Play(); // play the explosion
FindObjectOfType<GameManager>().EndGame();
}
}
I would change your approach. As I understand you already have an endTrigger [With a Collider Trigger] that ends the game if the player goes inside. So uncheck the trigger in the player collider and instead add that trigger to the rocks collider, so when the player crashes it will:
Activate the Particle System
Makes the rock invisible
End the Game
You can add this script to your rock and see how it works
public class RockTrigger : MonoBehaviour {
public GameManager gameManager;
ParticleSystem myParticleSystem;
void Awake()
{
myParticleSystem = GetComponent<ParticleSystem>();
}
void OnTriggerEnter(Collider other)
{
myParticleSystem.Play();
GetComponent<MeshRenderer>.enabled = false;
gameManager.GetComponent<GameManager>().EndGame();
}
}
Note about the OnTriggerEnter: In case you only have the player moving in the scene this is fine like this (I use the same pattern you used in EndGame),
but in case there were other GameObject with a RigidBody moving in the
scene you should check if other is indeed the player. Usually tagging the player and the checking if(other.tag == "Player")
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Test : MonoBehaviour {
public Transform target;
// Update is called once per frame
void Update ()
{
}
private void OnTriggerEnter(Collider col)
{
if (col.gameObject.tag == "Test")
{
this.transform.position = target.position;
}
}
}
I have a ThirdPersonController and i want it to collide with a cube or cylinder.
The script is attached to the ThirdPersonController.
I tried to add either to the cylinder or the cube Rigidbody turned on/off the Use Gravity and the Is Kinematic but nothing. It's not getting to the event.
ThirdPersonController uses CharacterController and OnControllerColliderHit is used for that not OnTriggerEnter.
Note that you must move it with the Move function not directly by its transform in order for OnControllerColliderHit to be called.
void OnControllerColliderHit(ControllerColliderHit hit)
{
}
Every thing is correct but the thing wrong here is you are changing the position of the object which is colliding with a second object , but the thing id the thing is the collider is already there.....
As it's alternative try to print any statement when collision happens like this
private void OnTriggerEnter(Collider other)
{
if (other.tag==your_tag)
{
print("message");
}
}