Basically on my map I'm trying to use Physics.CheckBox detect when the player is in certain areas to determine where my enemies will spawn at. I am using a layer mask to detect when its colliding with the player and Gizmos to visualize this box in the editor. The issue I'm having is that it will return true even when the player isn't inside the box. I have verified every single other game item does not have the player layer mask causing it to return true when it hits something else. The kicker is Physics.CheckSphere works perfectly except for the fact that my map is square, not circle, so I can't use check sphere because I can't cover all of the areas I need to cover.
Code for both is as follows, note that both of these lines are not in my script at the same time I alternated them out for testing:
atNeighborhood = Physics.CheckSphere(spawnAreas[0].transform.position, neighborhoodRange, playerLayer);
atNeighborhood = Physics.CheckBox(spawnAreas[0].transform.position, neighborhoodRange, Quaternion.identity, playerLayer);
Why would the CheckBox return true when colliding with items not in the layer mask but the CheckSpere works perfectly and only returns true when colliding with the player? Anyone have any idea?
LET ME KNOW IF THERE ARE ANY PROBLEMS OR ERRORS IN COMMENTS. THANKS!
Ok. CheckBox can get kind of confusing sometimes. I would reccomend something else.
You could use Empty Game Objects with colliders on them and put them where ever you want. IsTrigger must be set to true. Imagine these as "zones", where whenever you step in one, something can happen.
All you have to do is set a certain tag to each zone to activate different things.
Note: Player does not need rigidbody, but it would be a whole lot less messy if you did.
Here is a script if your player does have a rigidbody (put this script on your player):
void OnTriggerEnter(Collider obj)
{
if (obj.gameObject.CompareTag("Zone 1"))
{
SpawnZombies();
}
}
Player doesn't have rigidbody:
If your player does not have a rigidbody, you could put a bunch a script on each one called "zone activator".
Important Notes for this version:
Your player must have a collider and a unique tag.
On each zone add a rigidbody.
Make sure detectCollisions is false!
Make sure useGravity is false!
This zone detector should have it's collider be a trigger;
(You do not want this thing to move!)
You can now create a script that goes on each zone:
public string message;
public bool inZone;
void OnTriggerEnter(Collider obj)
{
if (obj.gameObject.CompareTag("player"))
//Or set it to whatever tag the player has
{
inZone = true;
}
}
void OnTriggerExit(Collider obj)
{
if (obj.gameObject.CompareTag("player"))
//Or set it to whatever tag the player has
{
inZone = false;
}
}
You must then reference this in the player's script
public ZoneDetector[] allZones;
void Update()
{
//.....
foreach (ZoneDetector zone in allZones)
{
if (zone.inZone == true)
{
if (zone.message == "zone 1")
{
DoZone1();
}
if (zone.message == "zone 2")
{
DoZone2();
}
}
}
}
Related
here is my current code:
public GameObject enemy;
void OnCollisionEnter(UnityEngine.Collision collisionInfo)
{
if (collisionInfo.collider.tag == "sword")
{
Debug.Log("works");
enemy.SetActive(false);
}
else
{
Debug.Log("doesnt work");
}
}
i have attached this to the enemy and also i tried a different script attached to the sword
void OnTriggerStay(Collider col)
{
if (Input.GetButtonDown("Fire1"))
{
if (col.GetComponent<Collider>().tag == "enemy")
{
Destroy(col.gameObject);
}
}
}
both codes don't work, it seems that the problem isnt with the sword collision cus i have also added the tag to another gameobject and it doesnt work. i looked online but havent found anything that works so fat
update: it seems that i have forgot you need a rigid body for collision detection. simple mistake but it made my code not work!
For collision enter to work, both the sword and the enemy colliders need to have the "IsTrigger" box unticked.
For on triggerstay is the opposite, both need to have that box ticked.
Basically, Triggers do not collide they call that OnTriggerEnter function, while non-triggers use the OnCollisionEnter.
I Have a player which gets childed to a game object when it walks up to a trigger now I want the player's parent to become null again after space is pressed because I'm trying to make a rope system, and it's required for the player to be able to de-attach from the rope
This is the script that's supposed to attach/detach the player from the rope
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AttachToRope : MonoBehaviour
{
public GameObject objectToParentTo;
public GameObject objectWithSwingScript;
// Start is called before the first frame update
private void OnTriggerEnter(Collider collider)
{
if (collider.gameObject.tag == "Rope")
{
transform.parent = objectToParentTo.transform;
objectWithSwingScript.GetComponent<playerscript>().enabled = true;
GetComponent<PlayerController>().enabled = false;
GetComponent<CharacterController>().enabled = false;
GetComponent<Swinging>().enabled = false;
}
}
private void OnTriggerStay(Collider collider)
{
if (Input.GetButtonDown("Jump"))
{
transform.parent = null;
objectWithSwingScript.GetComponent<playerscript>().enabled = false;
GetComponent<PlayerController>().enabled = true;
GetComponent<CharacterController>().enabled = true;
GetComponent<Swinging>().enabled = true;
Debug.Log("Deattached");
}
}
}
What happens when the player enters the trigger is that the scripts that make the player move get disabled and then it gets chilled to the last section of the rope now in ontriggerstay i want it to check if space is pressed and re-enable all the scripts that are required for the player to move (which does not work) but since nothing in there works i tried to debug.log but even that does not work so if anyone knows how to fix this please help me
From the OnTriggerStay documentation: The function is on the physics timer so it won't necessarily run every frame.
Functions on the physics timer (e.g. FixedUpdate()) don't play nicely with Input.GetButtonDown because they don't run every frame. Instead, they run on a fixed timestep, 0.02 seconds by default.
The solution is to put calls to Input.GetButtonDown into Update(). For instance, in this example you could have a boolean member variable isJumpPushed and set it to true in Update() when the jump button is pushed and the player is attached, and then check that value in OnTriggerStay.
--
A note about debugging:
I tried to debug.log but even that does not work
If your Debug.Log isn't showing a log in the console, that still tells you something important. It tells you that code path isn't getting called. That's an important clue for you to figure out what's really going on. To further narrow down the problem, you could move the Debug.Log statement outside the if statement. This would show that it's Input.GetButtonDown that isn't returning true when you think it is.
I have a player object which has (along with other components and objects) a Rigidbody2D, a Collider2D, a PhotonView, and a script called "PhotonLagCompensationView" attached to it. PhotonLagCompensationView syncs the position and velocity of the attached Rigidbody2D, and applies lag compensation like so:
public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
{
if (stream.IsWriting)
{
stream.SendNext(rigidBody2D.position);
stream.SendNext(rigidBody2D.velocity);
}
else
{
networkedPosition = (Vector2)stream.ReceiveNext();
networkedVelocity = (Vector2)stream.ReceiveNext();
float lag = Mathf.Abs((float)(PhotonNetwork.Time - info.SentServerTime));
networkedPosition += networkedVelocity * lag;
}
}
void FixedUpdate()
{
if (!photonView.IsMine)
{
rigidBody2D.velocity = networkedVelocity;
rigidBody2D.position = Vector2.Lerp(
rigidBody2D.position, networkedPosition, Time.fixedDeltaTime * interpolateRate);
}
}
The issue is when I try to call Rigidbody2D.AddForce() on that GameObject, the velocity wont even stutter. What blows my mind about this though is that when I call the EXACT SAME FUNCTION on a different script, it works just fine on all players in the room.
The script that is not working is "KnockBackOnTrigger" which is attached to an object which is instantiated over the network by the player. This object has a Collider2D which is a trigger, and a PhotonView. The OnTriggerEnter2D callback is working just fine. It prints "trigger", and I've even Debug.logged the AddForce() parameters, and a TryGetComponent<>() to make sure the Rigidbody is being recognized and it's applying force properly. The script applies force like this:
void OnTriggerEnter2D(Collider2D collider)
{
if(collider.gameObject.layer == 9 && collider.gameObject != PlayerManager.LocalPlayerInstance)
{
Debug.Log("trigger");
collider.gameObject.GetComponent<Rigidbody2D>().AddForce(
new Vector2(this.transform.localScale.x * knockBackForce, 0),ForceMode2D.Impulse);
}
}
Triggers show up, Rigidbody2D shows up, no moveme
The script that is working is a script attached to the "Lava Blocks" Gameobject which is a tilemap object. The tilemap object for the lava blocks has all the tilemap components attached to it (map, renderer, collider) and they work as intended, as well as the script attached to it. The "LavaBlocks" script works like this:
void OnCollisionEnter2D(Collision2D collision)
{ // everything inside this statement will happen to the player when it touches lava.
if (collision.gameObject.layer == 9)
{
collision.gameObject.GetComponent<Rigidbody2D>().AddForce(
Vector2.up * upwardForce, ForceMode2D.Impulse);
}
}
So whenever a player touches one of the Lava tiles' collider, it bounces upward.
Additionally, I've tried setting the velocity of the Rigidbody2D, which did not work either. This is in fact what I originally wanted to do with the script, but I tried AddForce() to see if that would work.
At one point I even tried to just use the player's CharacterController2D.Move() function to just smack the player's position some units to the left/right, and even this did not do anything.
I try to judge a player's approach to a monster using "OverlapSphere."
But somehow it doesn't work the way I want it to.
Is there anything wrong with the code below?
bool IsPlayerNear()
{
Collider[] colls = Physics.OverlapSphere(transform.position, 3f);
foreach(Collider hit in colls)
{
if(hit.gameObject.tag == "Player")
return true;
}
return false;
}
The player character has a capsule collider and "Player" tag.
But the "colls" array contains nothing.
A frequent cause of this sort of problem is that the capsule collider is attached to a child or parent of the tagged gameobject, so maybe check that, your code looks OK to me.
In Unity I want to change scenes when the player enters a certain area. The area has box collider and it is set as a trigger, and the script is attached to that area, however when the player enters that area and presses up on their keyboard, nothing happens. I have no syntax errors and it says everything is fine. What could the issue be?
Here is the code:
var Level = "";
var Player = "";
function OnTriggerStay(other : Collider) {
if(other.tag == Player){
if(Input.GetKeyUp("up")){
Application.LoadLevel(Level);
}
}
}
Revised code:
var Level = "";
var Player = "";
function OnTriggerStay (consolelog("Hello"))l;
{
if(other.tag == Player){
if(Input.GetKeyDown("up")){
Application.LoadLevel(Level);
}
}
}
So your code is Ok. I setup new project.And your code works fine.
Possible pitfalls:
1. You misspell either player tag either level name
2. You did not add level in build settings
3. One of colliders has to have rigidbody - docs
P.S. Problem was with a setup: mix colliders 2d and 3d.