Other
How to assign an absolute area to a moving gameObject?
Hi, I am new to Unity, there may be a simple API for me to handle my problem, but I am having a tough time to find one.
Problem
I am building a 2d Game and I am making an enemy that only chase player in a specific area. The area should be an absolute position, for instance -- a room, that does not move with enemy gameObject and enemy gameObject is also able to detect the player when player is in the area. I am seeking for a solution that is neat and cheap.
Tried implementation
I am currently using the some method similar to the following to detect collision inside a certain absoulte area:
public Collider2D[] CheckCollisionByPositionAll(Vector2 position, float range, LayerMask layer) {
// get collisions in given position
Vector2 leftUpCorner = new Vector2(position.x - range, position.y + range);
Vector2 rightBottomCorner = new Vector2(position.x + range, position.y - range);
return Physics2D.OverlapAreaAll(leftUpCorner, rightBottomCorner, layer);
}
public bool CheckCollisionByPosition(Vector2 position, float range, LayerMask layer) {
// is there collisions in given position
Collider2D[] cols = CheckCollisionByPositionAll(position, range, layer);
return cols.Length != 0;
}
Reasons why I think my implementation is bad
However, I find some problems with my current implementation
I need to call this method for each frame and I am not sure how expensive OverlapAreaAll is. And I want to make sure / be recommended some better solutions.
Different enemies care about different position, such as Enemy1 cares about Room1 only, while Enemy2 only cares about Room2. For making an absoulte position that does not move with enemy, I should not assign the position as an component of enemy gameObject. If so, the Hierarchy will be messy, because the relationship between positions and the enemies is not clear.
The position is not virtual, I have to do calculation to specify an area for enemy. I prefer a way that is more virtual like
BoxCollider2D
. (You can resize by dragging).
Maybe my next try
I am thinking of a way: create a empty gameObject and assign a BoxCollider2D component, speicify the size for collider, and rename + tag gameObject to something related to enemy's name. In enemy's script's awake()
, i can find the collider with GameObject.Find(__NAME__)
.
But ...
to be honest, I feel like this way is too tedious and overkilling.
Can anyone help me find a better solution?
what you are doing is fine. but if you want optimise you can use one of the below methos.
1
Attatch a circle collieder as trigger arround the enemy room up to what ever range you want and check like and attatch the script to the room object.
public EnemyScript enemyScript;
void OnTriggerEnter2d(collieder2d other) {
if(other.tag == "Player"){
enemyscript.inPlayerRange = true;
}
}
void OnTriggerExit2D(collieder2d other){ if(other.tag == "Player"){ enemyscript.inPlayerRange = false; } } now in the enemy Script
public bool inPlayerRange = false;
void Update(){ if(inPlayerRange){ // do your stuff....... } }
2
public Transform _player;
public Transform _room;
public float range;
void Update(){
float playerDistane = vector3.Distance(_room.position,_player.position);
if(playerDistane
// do your stuff.....
}
}
// declare _player transfrom, room and range in the inspector.
in my opinion 2nd method is well optimised.
Answer by quans1 · Sep 25, 2019 at 05:35 AM
Okay... I just figured out how to assign an absolute area to a moving gameObject. You can just simply make a parent gameObject that won't move on the top of your moving gameObject. This means that assigning your moving gameObject(I call this Main Object, since I do most of my scripting at this gameObject) to the child of the parent. And assign an absolute area to be another child, which is also sibling of the the main gameObject... Since your parent gameObject won't move, your absolute area won't move either... This is neater since you can make the parent object to be prefabs, therefore, it becomes reusable, and you won't need to manually drag and drop your gameObjects around every time.
This way the gameObject will be able to detect the collisions from the absolute area, such as a room.
Follow this Question
Related Questions
Steam Leaderboards in Unity, upload time since level load 0 Answers
How do i make a collage image in Unity? 0 Answers
Just updated to newest Unity version but something's missing 0 Answers
MonoDevelop Unity API reference function with wrong path. How to Fix it? 1 Answer
Is `TerrainData.SetHeights()`permanent? If yes, how to make it non-permanent? 2 Answers