I have a very annoying bug, and I can't get rid of it.
The situation is, that I have a parent with the following script attached, and a trigger box2d collider. It has a child, with a rigidbody2d(kinematic, gravity=0, freeze position x, and rotation z), a sprite renderer and a polygon collider (with 4 edges).
My problem is, when the scene is loaded, sometimes my child objects (always random how much of them and which ones), jumps to transform.position 0,0,0.
I link the script, that is attached to the parent
using UnityEngine;
using System.Collections;
public class FallingSpikeHazard : MonoBehaviour
{
public GameObject spike;
private Rigidbody2D spikeRigidbody;
[SerializeField]
private Vector3 startPosition;
void Awake ()
{
startPosition = spike.transform.localPosition;
}
void Start ()
{
spikeRigidbody = spike.GetComponent<Rigidbody2D> ();
Helper.JustReset += ResetMe;
Invoke ("CheckPosition", Time.deltaTime);
}
void CheckPosition ()
{
if (spike.transform.localPosition != startPosition) {
Debug.LogError ("t1" + spike.transform.localPosition);
spike.transform.localPosition = startPosition;
Debug.LogError ("t2" + spike.transform.localPosition);
}
}
void OnDestroy ()
{
Helper.JustReset -= ResetMe;
}
void ResetMe ()
{
spikeRigidbody.gravityScale = 0;
spikeRigidbody.isKinematic = true;
if (startPosition != Vector3.zero) {
spike.transform.localPosition = startPosition;
}
}
void OnTriggerEnter2D (Collider2D other)
{
if (other.gameObject.tag.Equals ("Player")) {
spikeRigidbody.isKinematic = false;
spikeRigidbody.gravityScale = 1;
}
}
}
Events are not called, in other hand, if I disable the script, it keeps happening. Nothing have reference to these GameObjects. I don't have animations, or animator attached.
What could cause my problem?
You need to have a Rigidbody2D component in the parent GameObject in order for the OnTriggerEnter function to be called.
Related
I am working on a small game for a school project, in which my player needs to attack enemies in a level. My plan is to have a collider that is enabled in an attached script, and then disabled when the attack is done. My current problem is that that the collider does not flip the way it is supposed to, it seems to flip directly on the overall x axis instead of flipping in the x axis related to the player. It is a child of the player so I am clueless as to why it is doing this. Any solutions or other approaches would be greatly appreciated. I will attach the current script that controls the collider below.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class VerticalSword : MonoBehaviour
{
//Variables use to active the colliders
Collider2D AttackColliderVertical;
//Variables for the location of the collider
Vector2 attackOffset;
private void Start()
{
AttackColliderVertical = GetComponent<Collider2D>();
attackOffset = transform.position;
AttackColliderVertical.enabled = false;
}
public void FixedUpdate()
{
attackOffset = transform.position;
}
public void AttackUp()
{
AttackColliderVertical.enabled = true;
if (attackOffset.y > 0)
{
transform.position = attackOffset;
}
else if (attackOffset.y < 0)
{
transform.position = new Vector2(attackOffset.x, (attackOffset.y * -1)); //I think the problem is somewhere in this if and else if statement
}
print("Attack up successful"); //Error checking (This works when run)
}
public void AttackDown()
{
AttackColliderVertical.enabled = true;
if (attackOffset.y > 0)
{
transform.position = new Vector2(attackOffset.x, (attackOffset.y * -1));
}
else if (attackOffset.y < 0)
{
transform.position = attackOffset; //I think the problem is somewhere in this if and else if statement
}
print("Attack down successful"); //Error checking (This works when run)
}
public void StopAttack()
{
AttackColliderVertical.enabled = false;
}
}
Use transform.localPosition, not transform.position (that's its world space position). You need to change it everywhere in this script; the Start() function and the two attack functions
I'm trying to animate / transform a gameObject movingObject from it's spawn position to the destination. I believe the issue is somewhere in the implementation of the IncrementPosition function.
Rather than moving the one cube from A to B. The script spawns multiple cubes until it gets to B. Can you see where I'm going wrong?
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class onClickSpawnMove : MonoBehaviour
{
public float speed;
public GameObject randomSpawn;
private GameObject movingObject;
private Vector3 destination;
void Start()
{
Spawn();
}
void Update()
{
SetDestination(movingObject.transform.position);
if (destination != movingObject.transform.position) {
IncrementPosition();
}
}
void IncrementPosition()
{
float delta = speed * Time.deltaTime;
Vector3 currentPosition = movingObject.transform.position;
Vector3 nextPosition = Vector3.MoveTowards(currentPosition, destination, delta);
movingObject.transform.position = nextPosition;
}
void Spawn() {
Vector3 spawnPosition = new Vector3(10, 0, 0);
movingObject = Instantiate(randomSpawn, spawnPosition, Quaternion.identity);
}
public void SetDestination(Vector3 value)
{
destination = new Vector3(20, 0, 0);
}
}
There are several ways to call the Spawn / Start method casually:
gameObject.AddComponent<onClickSpawnMove>(); the Start method will be invoked again.
Instantiate a prefab that onClickSpawnMove script is attached already.
gameObject.SendMessage("Start"); maybe, but rarely seen.
You can add a log or break point to check when the Spawn / Start method is called.
Print the hash code will help you know the different onClickSpawnMove instances.
And you can click the message in the console to know which GameObject is.
void Start()
{
Spawn();
Debug.Log("Start " + this.GetHashCode(), this);
}
The problem is that I what to create an openable door. This door should open when the player enter the Box Collider which is connected to the door. But the problem is when the door begins to open and to rotate, Collider starts to rotate too which brings me a lot of problems with usind such an idea. I try to create EmptyObject with its Collider but I can't connect this Collider with script and OnTriggerEnter function itself. Maybe I don't understand something, who knows, I'm just a begginer. How knows how to help, please write an answer.
My code if somebody needs it:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class openDoor : MonoBehaviour {
public Vector3 Rotation_;
private int i;
public float speed;
bool opentheDoor;
bool closetheDoor;
// Use this for initialization
void Start () {
opentheDoor = false;
closetheDoor = false;
}
// Update is called once per frame
void Update () {
if (opentheDoor == true) {
this.transform.Rotate (Rotation_ * Time.deltaTime * speed);
i += 1;
if (i == 70) {
opentheDoor = false;
i = 0;
}
}
if (closetheDoor == true) {
this.transform.Rotate (-Rotation_ * Time.deltaTime * speed);
i += 1;
if (i == 70) {
closetheDoor = false;
i = 0;
}
}
}
void OnTriggerEnter (Collider other) {
if (other.gameObject.tag == "Player") { {
opentheDoor = true;
}
}
}
void OnTriggerExit (Collider other) {
if (other.gameObject.tag == "Player") {
closetheDoor = true;
}
}
}
This is how i would handle the scenerio
Take
DoorHandler.cs
public class DoorHandler : MonoBehaviour {
public Door door;
private void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Player"))
{
door.OpenDoor();
}
}
}
This should be attached to Parent of the door.
Next Take
Door.cs
public class Door : MonoBehaviour {
public bool isOpened = false;
public void OpenDoor()
{
if (!isOpened)
{
isOpened = true;
Debug.Log("OPEN");
//OPEN DOOR CODE!
}
}
}
Attach this to the Door GameObject
NOTE
The hierarchy would be like DoorHandler->Door->DoorModel (where Door is just an empty gameobject pivot of the Door)
In DoorHandler GameObject attach BoxCollider and Check Mark IsTrigger.
Also Player SHOULD HAVE A RIGIDBODY (preferably Kinametic) and obviously a collider
So When Player enters the DoorHandler's Collider -> The DoorHandler's OnTriggerEnter will be triggered and finally Call the Door to OpenDoor()
Add another check in OnTriggerEnter that checks if the door is currently opening or not.
void OnTriggerEnter (Collider other) {
if (other.gameObject.tag == "Player" && !opentheDoor) {
opentheDoor = true;
}
}
attach the door to an empty object. put the trigger on the empty object. then make the ontrigger entry rotate the door, not the paent object, and the collider will remain in place.
Parent
-child(door)
-child(collider)
I'm trying to create objects that mark the cell that I can visit. I mark them with red square:
My code for creating objects:
using UnityEngine;
using System.Collections;
using System;
public class SpawnCheck : MonoBehaviour {
public GameObject checkObject;
public bool canSpawnCheck = true;
Vector2 boxSize;
public GameObject spawnedObject;
// Use this for initialization
void Start () {
Debug.Log("Into spawn check");
}
void OnTriggerEnter2D(Collider2D other) {
Debug.Log("Enter trigger collision");
canSpawnCheck = false;
if (other.gameObject.tag == "Target") {
Debug.Log ("Found Target");
}
if (other.gameObject.tag == "Wall") {
canSpawnCheck = false;
}
if (other.gameObject.tag == "Check") {
canSpawnCheck = false;
}
}
void OnTriggerExit2D(Collider2D other) {
Debug.Log("Exit trigger collision");
canSpawnCheck = true;
}
// Update is called once per frame
void Update () {
Debug.Log ("canSpawnCheck " + canSpawnCheck);
if (canSpawnCheck == true) {
Vector3 currentPosition = this.gameObject.transform.position;
Vector3 spawnPos = new Vector3 (Mathf.Round (currentPosition.x), Mathf.Round (currentPosition.y),0);
Debug.Log ("Physics.CheckSphere " + Physics.CheckSphere (spawnPos, 5));
if (!Physics.CheckSphere(spawnPos,5)) {
spawnedObject = (GameObject)Instantiate (checkObject, spawnPos, Quaternion.identity);
this.gameObject.GetComponentInParent<AILerp> ().possibleTargets.Add (spawnedObject);
}
}
}
}
My problem: as Physics.CheckSphere(spawnPos,5) always return false my code spawns too many red squares and spawn them upon each other. I want red squares to be created only once and never created on walls (white squares).
Your Check(Clone) GameObject has Box Collider 2D attached to it. Therefore every physics function you must use should be Physics2D.something not Physics.something. Notice the keyword there "2D".
If you use just Box Collider without the 2D in it, then you can use Physics.something. So, Physics.CheckSphere cannot be used with a 2D collider.
Check(Clone) is a SpriteRenderer, 2D Collider is appropriate. You just need to use one of the Physics2D overlap functions such Physics2D.OverlapBox, Physics2D.OverlapArea or Physics2D.OverlapCircle. Which ever one you prefer.
I m coding a 2d platform game. In the game, there are allies and enemies walks toward each other. If they collide each other, their own timer script starts countdown and the health reducing by the time as periods. If a characters health equals to zero, i destroy that gameobject. I add some booleans each character to detect they are colliding each other or not. While colliding both gameobjects, if one destroys, other colliding gameobject still continius colliding, although there is no colliding object. This happens just other colliding object is destroyed.
public float setSpeed;
public bool enemyColliding;
float speed;
void Start () {
}
// Update is called once per frame
void Update () {
speed= setSpeed;
GetComponent<Rigidbody2D> ().velocity = new Vector2 (speed,GetComponent<Rigidbody2D>().velocity.y);
if (enemyColliding) {
attackAnimation ();
}
else
{
walkAnimation();
}
}
void OnTriggerEnter2D(Collider2D coll)
{
if (coll.gameObject.tag == "dusman" /*enemy*/ ) {
enemyColliding= true;
}
}
void OnTriggerExit2D(Collider2D coll)
{
if (coll.gameObject.tag=="dusman" /*enemy*/) {
enemyColliding= false;
}
}
void attackAnimation()
{
Animator animator = this.gameObject.GetComponent<Animator> ();
animator.runtimeAnimatorController = Resources.Load ("AllyWr2AttackAnim") as RuntimeAnimatorController;
}
void walkAnimation ()
{
Animator animator = this.gameObject.GetComponent<Animator> ();
animator.runtimeAnimatorController = Resources.Load ("AllyWr2WalkAnim") as RuntimeAnimatorController;
}
Any help please...
void OnTriggerExit2D(Collider2D coll)
{
enemyColliding= false;
}
try this