Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Animating rod rest position
#31
Sorry, new problem. The event rod.Onblueprintloaded is never being triggered
Reply
#32
(11-06-2021, 04:18 PM)Hakazaba Wrote: Sorry, new problem. The event rod.Onblueprintloaded is never being triggered

It is for me, tested using this script:

Code:
using UnityEngine;
using Obi;

[RequireComponent(typeof(ObiRod))]
public class OnBlueprint : MonoBehaviour
{
    void Awake()
    {
        GetComponent<ObiRod>().OnBlueprintLoaded += OnBlueprint_OnBlueprintLoaded;
    }

    private void OnBlueprint_OnBlueprintLoaded(ObiActor actor, ObiActorBlueprint blueprint)
    {
        Debug.Log("Loaded!");
    }
}

Make sure you subscribe to it in Awake(). Blueprints are initially loaded in OnEnable(): if you subscribe to the event later, the blueprint will be already loaded (and hence, the event will not be triggered until the blueprint is re-loaded).
Reply
#33
Code:
void SetStartPos(ObiActor actor, ObiActorBlueprint blueprint){
        print("Eventfired");
        if(followRig){
            //print("following "+followChain.Length);
            var Bendtwist = rope.solverBatchOffsets[(int)Oni.ConstraintType.BendTwist];
       
           

            int b = 0;
            int b2 = 0;
            bool batch = true;
            Quaternion prior = followChain[0].rotation*orientInverse[0]*particleOrigional[0];
            for (int i = 1; i<chain.Length-1;i++)
            {

                Quaternion next = prior;
                prior = followChain[i].rotation*orientInverse[i]*particleOrigional[i];
                if (batch){
                    solverConstraints.batches[0].restDarbouxVectors[Bendtwist[0]+b] = ObiUtils.RestDarboux(next,prior);
                   
                    batch = false;
                    b++;
                }
                else {
                   
                    solverConstraints.batches[1].restDarbouxVectors[Bendtwist[1]+b2] = ObiUtils.RestDarboux(next,prior);
                    batch = true;
                    b2++;
                }

                solver.positions[rope.solverIndices[i]] = followChain[i].position;
                solver.orientations[rope.solverIndices[i]] = followChain[i].rotation*orientInverse[i]*particleOrigional[i];
            }

            for(int i  = 0; i<rope.particleCount;i++){
                int index = rope.GetParticleRuntimeIndex(i);
               
            }
           
        }
    }
    private void Awake() {
   
        rope.OnBlueprintLoaded += SetStartPos;
    }
This my code. rope is a ObiRod.
Eventfired never shows up in my console...

It turns out this is because this is a different object, and on enable is before the awake of this object


Also im getting a lot of crashes in my scene the heavier it gets with obi actors
Reply
#34
(11-06-2021, 06:54 PM)Hakazaba Wrote: [...]
It turns out this is because this is a different object, and on enable is before the awake of this object

The call order of event functions in different MonoBehaviours is undefined in Unity, unless you specify otherwise:
https://docs.unity3d.com/Manual/class-MonoManager.html

(11-06-2021, 06:54 PM)Hakazaba Wrote: Also im getting a lot of crashes in my scene the heavier it gets with obi actors

I've worked with scenes with hundreds of actors in the past, didn't have any issues. Can you share a crash log?
Reply
#35
Aparently the order of operations is a little bit more complicated according to this thread, in regards to OnEnable: https://forum.unity.com/threads/onenable-before-awake.361429/

Ill send logs via email
Reply
#36
(16-06-2021, 03:33 PM)Hakazaba Wrote: Aparently the order of operations is a little bit more complicated according to this thread, in regards to OnEnable: [url=https://forum.unity.com/threads/onenable-before-awake.361429/]https://forum.unity.com/threads/onenable-before-awake.361429/

That thread describes the usual, documented behavior:

- For each object, Awake() is always called before the same object's OnEnable().
- For different objects, there's no guaranteed relative ordering of their events unless you specify otherwise in the Script Execution Order window.

That means if you have 2 objects with no hand-specified execution order, you can get several call orders:

#1) object1.Awake()
#2) object1.OnEnable()
#3) object2.Awake()
#4) object2.OnEnable()

#1) object1.Awake()
#3) object2.Awake()
#2) object1.OnEnable()
#4) object2.OnEnable()

#1) object2.Awake()
#2) object2.OnEnable()
#3) object1.Awake()
#4) object1.OnEnable()

...etc.

What you will never get is an object's OnEnable called before its Awake() function. So, this cannot ever happen:

#1) object2.OnEnable()
#2) object2.Awake()

See:
https://docs.unity3d.com/Manual/ExecutionOrder.html

Specifically, the "Update Order" section.
Reply
#37
Yes, the problem before was that i had two separate objects...
However, i copied your script exactly, placed it on the same object as the rod. And it worked, last night. Today it does not.
Reply
#38
(16-06-2021, 11:43 PM)Hakazaba Wrote: Yes, the problem before was that i had two separate objects...
However, i copied your script exactly, placed it on the same object as the rod. And it worked, last night. Today it does not.

The same applies to different scripts on the same object. By default, call order is undefined for different scripts.

Quoting the documentation I linked you to yesterday:
https://docs.unity3d.com/Manual/ExecutionOrder.html

Quote:You cannot specify the order in which an event function is called for different instances of the same MonoBehaviour subclass. For example, the Update function of one MonoBehaviour might be called before or after the Update function for the same MonoBehaviour on another GameObject — including its own parent or child GameObjects.

You can specify that the event functions of one MonoBehaviour subclass should be invoked before those of a different subclass (using the Script Execution Order panel of the Project Settings window). For example, if you had two scripts, EngineBehaviour and SteeringBehaviour, you could set the Script Execution Order such that EngineBehaviours always updates before SteeringBehaviours

Simply use script execution order to specify that your script should run before ObiActor.

A cleaner solution is to control actor loading yourself (which I believe you currently do, if memory serves me well). Simply subscribe to OnBlueprintLoaded before parenting the actor to a solver.
Reply
#39
Oh my! I actually didnt know about the script executionorder panel window at all! I dont think i control actor loading either. Thank you for drawing my attention to this.
Reply
#40
I'm sorry this has gone on so long, i have a new issue.

If i edit the position and orientation of the particles on that event, The particles positions become {NAN,NAN,NAN} in the next update statement when i try to retrieve them with rod.GetParticlePosition(). I wonder if perhapse i am causing extreme accellerations by changing them, do i need to set the particles inertia to 0 somehow afterward? Or is the particle position value in local space related to the prior particle? At the moment i am supplying world coordenates.
Reply