0

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?

Sciguy77
  • 349
  • 6
  • 14
  • Give your Expando the Player object and access it with ```ExpandoInstance.PlayerInstance.AimTargetPos```. Otherwise, another hacky way of doing it is using a 1-length array, ```Expando.AimTargetPos[0]``` – Immersive Nov 16 '20 at 00:22

1 Answers1

1

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.

Ron
  • 1,806
  • 3
  • 18
  • 31
  • Thanks! This is what I ended up doing. What's wrong with dynamics? From what I've read they're really well optimized. I chose dynamics because it seemed to fit my state machine. A dynamic params ExpandoObject is passed into each state, holding the values and references that each state needs for its calculations. And each state requires vastly different params, so aa dynamic params payload is generalized enough to be useable by all the various states. – Sciguy77 Nov 17 '20 at 05:33
  • Nothing officially wrong with them, I just personally dislike dynamics and love typed parameters. With well designed typed classes it's almost impossible to shoot yourself in the foot, but dynamics add a whole range of logical errors and api exposure – Ron Nov 17 '20 at 07:09