Search code examples
c#unity-game-enginepointersdynamicexpandoobject

Storing a c# reference or pointer to a Vector3 in a dynamic ExpandoObject()?


I have an instanced class Player() with a public Vector3 property AimTargetPos:

//Player.cs
private Vector3 aimTargetPos;
public Vector3 AimTargetPos => aimTargetPos;

Under certain conditions, AimTargetPos is updated with a new value every frame. In another class, AimTargetPos is stored by value in a dynamic ExpandoObject() as payload.aimTargetPos, then passed as a parameter to a function called, Enter(dynamic payload).

Since Player.AimTargetPos is still being updated every frame, payload.aimTargetPos will only have the correct Vector3 value during the same frame it is created and passed into Enter(). I need to be able to assign aimTargetPos to a local ref or pointer variable, so I can keep using aimTargetPos from the payload after this first frame. However I have not found a way to store a reference to Player.AimTargetPos in the dynamic ExpandoObject payload.

There are some hacky solutions I don't want to resort to:

  • Create a new Transform() just to hold the position Vector3, since transforms are by default passed by reference.
  • Rather than pass a reference or pointer in the payload ExpandoObject, just continuously read Player.AimTargetPos each frame to get the most up-to-date position value. This introduces a level of coupling I want to avoid.

According to this question there's not a one-line way to do it, but it does sound like there are options. If I can't hold a reference in a dynamic object, then perhaps I could store the address of Player.AimTargetPos, and use that address to create a ref or pointer once the payload is received in Enter()? But it seems like this is a needlessly abstruse way to go about it. Is there a simpler way to achieve this?


Solution

  • First of all I have to ask, why do you need using an ExpandoObject?

    99.9% of the time in my experience using typed objects is a perfectly good solution (and much cleaner).

    That being said, you can do the following:

    1. Store a delegate member in your EO which returns the target

    expando.playerTarget = (Func<Vector3>) (() => { return player.aimTarget; });

    1. Wrap the data in a class object and pass it instead

    My personal suggestion is avoid using dynamics when possible.