- Home /
Getting game logic object from GameObject
I have all my game logic contained within a GameManager class and I'm only using Unity as a graphics and input engine. None of my prefabs have any Unity components relating to behaviour (as that's all contained within GameManager). Background : I'm porting an old game from XNA to Unity.
I'm using raycasting within Unity to get a GameObject
from the scene when ever the mouse clicks it, this works fine and I'm able to access all components of the GameObject
.
public GameObject GetRayCastGameObject()
{
RaycastHit hitInfo;
Ray ray = mainCamera.ScreenPointToRay(Input.mousePosition);
Physics.Raycast(ray, out hitInfo);
if (hitInfo.transform != null)
{
return hitInfo.transform.gameObject;
}
return null;
}
However I'm having difficulty in translating that GameObject
into an object I hold programatically in a manager class.
Specifically :
I have a PlayField
class that holds an array of Blocks[X, Y]
. When I click on a block in the scene I want to take that reference I have to the GameObject
and pass it into my PlayField
class to 'damage' the block in Blocks[X, Y]
.
Conversely the other way round, when creating a block, I can do quite easily. I take the raycast on a mouse click, find where it's hit in the scene (Vector3) and create a new Block
within the Playfield
class. This then raises a domain event to instantiate a new Block
from a prefab at that location.
var woodenCrateCreatedDomainEvent = new WoodenCrateCreatedDomainEvent(this.inputManager.GetRayCastLocation(), this.PlayerPosition.rotation);
DomainEvents.Raise<WoodenCrateCreatedDomainEvent>(woodenCrateCreatedDomainEvent);
One solution I have thought of is to havean Identity
component on every Block
which will just be a GUID. I could then use GameObject.GetComponent()
to retrieve the GUID and pass it into a Playfield.DamageBlock(string GUID)
method. However this would mean that the Playfield
class would have to lookup a GUID match in its list of Block
s to find the Block
object that is hit, and when you have thousands of Block
s this will be quite slow - string matching over thousands and thousands of objects isn't exactly fast.
Is there a better way / a de facto way of translating from a Unity scene GameObject
into an object that I hold within the core game logic memory ?
Sudo code :
GameManager (empty Unity component with GameManager script) initialises.
GameManager (script C# code) constructor called.
GameManager initialises private class PlayField.
GameManager (script C# code) StartUp() method called by Unity.
GameManager calls PlayField.Generate()
PlayField creates a private array of `Blocks[X, Y]` blocks and holds these in memory.
PlayField calls UnityEngine.Instantiate("Block", position, rotation) for each `Block` in `Blocks[X, Y]`
Now the blocks exist in the game logic (in PlayField as Blocks[X, Y]
) and as a visual GameObject
in Unity
Game runs... and player in Unity clicks a block :
GameManager does ray tracing to find which Unity `GameObject` it is (as "gameObject")
GameManager matches `GameObject` to a game logic `Block` in the PlayField `Blocks[X, Y]` array
// How to do previous step as `GameObject` holds no information about `Block` in game logic or visa versa
GameManager updates game logic to perform action on `Block` e.g. reduces health
GameManager checks to see if `Block` is dead
GameManager removes `Block` from `Blocks[X, Y]` removing it from the game logic
GameManager calls UnityEngine.Destroy("gameObject") removing it from the graphics and input engine (Unity)
The one I can't seem to figure out is the "GameManager matches GameObject
to a Block
" step as it goes across from the Unity domain to the game logic domain.
Answer by $$anonymous$$ · Jul 21, 2014 at 08:47 PM
If I understood you correctly,you could try making the PlayField class a singleton and add it on an empty gameobject in the scene.That way you can reference it from anywhere without looking it up.Then when the raycast gets you an object that holds a Block component you can call PlayField.Instance.GetThisBlockAndDoWhatever(hitBlock).
GameObject go = GetRayCastGameObject();
Block hitBlock = go.GetComponent<Block>();
if(hitBlock != null){
PlayField.Instance.GetThisBlockAndDoWhatever(hitBlock);
}
Basically all the game logic sorted is sorted outside Unity, but I'm just using Unity for a rendering and input engine. I don't really want to store references to clones
as they mean nothing to the core game logic, but when a mouse clicks on a block in Unity (a clone
), that needs to translate into a Block
in the game logic. The prefab/clone in Unity holds no behaviour as that's all contained within the game logic itself.
It's been long since then but I saw this now so I'm gonna answer anyway. Since you don't want the objects to have any behaviour and hold any references you can use the name of the clone to contain the indexes of the PlayField block they represent("Clone[2,3]" as in PlayField[2,3]). Not elegant but if you don't want to use a lookup table and have bare gameobjects then it's the only way I can think of. Whenever you click on a clone,you can definitely get it's name.Therefore you can extract the indexes and send them along through your Playfield.DamageBlock(int row,int col)
Your answer
Follow this Question
Related Questions
How to store player model and then swap the model to an object I Raycast hit? 0 Answers
Reverse object position order 1 Answer
Distribute terrain in zones 3 Answers
Raycast isn't working as expected 1 Answer
Spawned tree not falling 1 Answer