Physics OverlapSphere does not detect Collision - unity3d

I wanted to create an collider on my players sword, that if he attacks that he would detect and via an animation event turn off/on an gameobject called (Damage Point) who was an script attached that would subtract the enemys health.
But somewhere it does not detect correctly. I tried to add the OnDrawGizmos function to see my sphere collider but even after making it bigger it does not detect.
The most strange thing about my issue is that im using the same code for my monster chest and my fantasy player, but for the chest it works but for the player it does not.
I created a class called PlayerDamage that is attached on an empty gameobject to the tip of my sword.
{
public class PlayerDamage : MonoBehaviour
public int damageAmount = 2;
public LayerMask enemyLayer;
void Update()
{
Collider[] hits = Physics.OverlapSphere(transform.position, 1.7f, enemyLayer);
if (hits.Length > 0)
{
if (hits[0].gameObject.tag == MyTags.ENEMY_TAG)
{
print("COLLIDED WITH ENEMY");
}
}
}
private void OnDrawGizmos()
{
Gizmos.DrawWireSphere(transform.position, 1.7f);
}
In another script called PlayerScript that is attached directly to the player I have a function called Attack:
void Attack()
{
if (Input.GetKeyDown(KeyCode.K))
{
if (!anim.GetCurrentAnimatorStateInfo(0).IsName(MyTags.ATTACK_ANIMATION) || !anim.GetCurrentAnimatorStateInfo(0).IsName(MyTags.RUN_ATTACK_ANIMATION))
{
anim.SetTrigger(MyTags.ATTACK_TRIGGER);
}
}
}
Also in the PlayerScript class there are two functions called ActivateDamagePoint and DeactivateDamagePoint, these are assigned to animation events for the attack animations.
void ActivateDamagePoint()
{
damagePoint.SetActive(true);
}
void DeactivateDamagePoint()
{
damagePoint.SetActive(false);
}
I double checked that everything is on his layer and that the tags are okay, but that did not solve my problem.
Like I said before for the chest I use the same code and it works, but unfortunately it does not work with my player. I also have the Activate and Deactivate DamagePoint functions in there and these are also called by the animation event for my chest attack animation.

Okay after 1hour of debugging I finnaly found the solution:
It was in the MyTags class (a helper class for all the string variables), the error was:
public static string ENEMY_TAG = "Enemey";
instead of:
public static string ENEMY_TAG = "Enemy";

Related

How do I delete collider on trigger in unity?

I am trying to make a check point, I want to make it so when the character hits the checkpoint, the collider turns off (I am open to using a raycast but that wasn't the current plan). I am still new to unity and I can't get the code to compile. I think my issue may be just not calling objects properly???
public class checkpoint : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
cp = GetComponent<Collider>();
cp.isTrigger = true;
object = GameObject.Find("Check Point");
}
private void OnTriggerEnter(cp)
{
cp.GetComponent(BoxCollider).isTrigger = false;
}
}
Not sure what is wrong
When you look at the code in your IDE, you will see red outlines underneath the exact points in your code that have issues. When you hover your cursor over these points the IDE will tell you what the issue is.
You can even use the Show potential fixes functionality and the IDE can often fix the issue for you automatically.
Here is the code modified so that it compiles.
public class checkpoint : MonoBehaviour
{
Collider cp;
// Start is called before the first frame update
void Start()
{
cp = GetComponent<Collider>();
cp.isTrigger = true;
GameObject gameObject = GameObject.Find("Check Point");
}
private void OnTriggerEnter(Collider other)
{
cp.isTrigger = false;
}
}
You were missing declarations for your cp and object variables. Additionally object is a reserved keyword in C#, so you can't use it as a variable name.
On the OnTriggerEnter function declaration the cp parameter was missing its type Collider.
In the body of the method the GetComponent call has incorrect syntax.
UPDATE: You can use the Destroy method to destroy the Collider component when something enters inside its bounds for the first time.
[RequireComponent(typeof(Collider))]
public class Checkpoint : MonoBehaviour
{
void Reset()
{
var collider = GetComponent<Collider>();
collider.isTrigger = true;
}
private void OnTriggerEnter(Collider other)
{
var collider = GetComponent<Collider>();
Destroy(collider);
}
}
If you want to destroy the whole GameObject that contains the checkpoint component and the Collider component you can use Destroy(gameObject);.

How to show a trigger only when pointing to it directly?

I created a transparent cube trigger and I placed it in front of closed doors, so whenever the player walks near the door a message appears saying "this door is locked".
However, I want the message to be gone whenever the player is Not pointing to the door. currently, it shows even when I turn around, the player needs to walk away from the door to make the message disappear.
Here is my code:
public class DoorsTrigger : MonoBehaviour
{
public GameObject partNameText;
private void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Player"))
{
partNameText.SetActive(true);
}
}
private void OnTriggerExit(Collider other)
{
if (other.CompareTag("Player"))
{
partNameText.SetActive(false);
}
}
}
How can I modify it to achieve my goal?
Here is a simple example using Vector3.Angle() to get the direction the player is facing relative to that trigger.
public class DoorsTrigger : MonoBehaviour
{
public GameObject partNameText;
private void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Player"))
{
//Assuming 'other' is the top level gameobject of the player,
// or a child of the player and facing the same direction
Vector3 dir = (this.transform.position - other.gameObject.transform.position);
//Angle will be how far to the left OR right you can look before it doesn't register
float angle = 40f;
if (Vector3.Angle(other.gameObject.transform.forward, dir) < angle) {
partNameText.SetActive(true);
}
}
}
private void OnTriggerExit(Collider other)
{
//Make sure the text is actually showing before trying to disable it again
if (other.CompareTag("Player") && partNameText.activeSelf)
{
partNameText.SetActive(false);
}
}
}
Alternatively, you can keep your trigger mostly as is, and do a ray cast from the player to see if they are looking at the door.
//Put this snippet in a function and call it inside the player's Update() loop
RaycastHit hit;
Ray ray = new Ray(this.transform.position, this.transform.forward);
if(Physics.Raycast(ray, out hit))
{
//Tag the gameObject the trigger is on with "Door"
if(hit.collider.isTrigger && hit.collider.CompareTag("Door"))
{
//Here is where you would call a function on the door trigger to activate the text.
// Or better would be to just have that code be on the player.
// That way you can avoid unnecessary calls to another gameObject just for a UI element!
}
}

How to create an object to follow my Player

I'm looking for a way to do something like this:
Gradius
In this game, orbs are following the player. How to do this in Unity where my orbs are following my Player.
Thanks!
A simple solution that i have thought is, lets say i have a player and it is holding it's previous position at start and whenever it moves lets say 5 units then we say to the object that will follow it to follow it's previous position and then we update player's previous position to it's current position and we follow same steps.
I have created a simple test scene and followed these steps :
I have created 2 game objects called Player and FollowPlayer
I have wrote the script below and attached it to the Player
public static event Action<Vector3> FollowMe;
[SerializeField] private float _followDistance;
private Vector3 _previousPosition;
private void Start()
{
_previousPosition = transform.position;
}
private void Update()
{
if(Vector3.Distance(transform.position,_previousPosition) > _followDistance)
{
if(FollowMe != null)
{
FollowMe.Invoke(_previousPosition);
}
_previousPosition = transform.position;
}
}
Then for the FollowPlayer object i have wrote the script below and attached to it
private void Start()
{
Player.FollowMe += OnFollowMe;
}
private void OnDestroy()
{
Player.FollowMe -= OnFollowMe;
}
private void OnFollowMe(Vector3 position)
{
transform.position = position;
}
Again, this is a simple follow script same logic in the Gladius game and i am sure you can use this idea and make it more generic and usable.

How to add collision physics in Unity Mapbox World Scale?

In World Scale AR, I want to move to an object I placed using SpawnOnMap. When I touch that object, I want that object to be erased. I made the Player have a script called PlayerController. I made a tag for the object so that when it touches, it should destroy or set it active. When I walk towards the object, nothing happens. I've tried OnTriggerEnter and OnCollisionEnter already. Is there some kind of method I'm missing that Mapbox provides?
public class PelletCollector : MonoBehaviour
{
public int count = 0;
// Start is called before the first frame update
void Start()
{
}
private void OnCollisionEnter(Collision other)
{
if (other.gameObject.tag == "Pellet")
{
count++;
Debug.Log("Collected Pellets: " + count);
other.gameObject.SetActive(false);
//Destroy(other.gameObject);
}
}
}

OnCollisionEnter in unity won't call function

I'm a complete unity novice. I want to make a simple scene where you have three lives and you lose a live if you collide with a cube. This is my script:
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class Lives : MonoBehaviour {
public Transform player;
public static int lives;
public Image live1;
public Image live2;
public Image live3;
// Use this for initialization
void Start () {
lives = 3;
live1.enabled = true;
live2.enabled = true;
live3.enabled = true;
}
void Update () {
DisplayOfHearts();
}
public static void Damage() {
lives -= 1;
}
public void OnCollisionEnter(Collision col) {
if (col.gameObject.tag == "cube") {
Lives.Damage();
}
}
public void DisplayOfHearts() {
if (lives == 2) {
live3.enabled = false;
}
else if (lives == 1) {
live2.enabled = false;
}
else if (lives == 0) {
live1.enabled = false;
}
}
}
What happens is the player can't move through the cube but the amount of lives stays three. Is there something I'm missing?
The problem is you have attached the script to a wrong game object. The script and the collider must be attached to the same game object.
Unity methods inside a MonoBehaviour script (such as OnEnable, Update, FixedUpdate, Awake, Start, OnTriggerEnter, OnCollisionStay, etc..) only work for the game object which the script is attached to.
If you attach the script to another game object don't expect any of those to work. Update only works while that game object is active. OnCollisionEnter only works when a collision occurs on a collider which is attached directly to that game object. (it doesn't even work when a child has the collider instead of the actual game object where script is attached to)