playMaker

Author Topic: Trying to make a custom action, (method call but requires formal Parameters)  (Read 2636 times)

Orjax

  • Playmaker Newbie
  • *
  • Posts: 21
  • Father/son team, self taught, love learning
I bought a great resource from the asset store called Psoft Body Deformation.
Great product, and I'm very happy with it.  Only problem is I'm a newb and trying to code a custom action to call a method.

Been trying for hours and hours.  It requires formal parameters that I can not seem to get right.  Coding is fun but it's like learning a new language, and takes a lot of pointers and practice.  Please help.

I have watched this tutorial about 10 times (and others)  but I cant quite get it.
here is my code, (I wont include the code from the asset, piracy) :-)

I'm trying to call method deformPoint, and I have set a"touch object" "hit point" as a vector 3.  (This project is for touch screen mobile)

This is the example code to call method (but its keyboard and mouse Obviously)

      if(Input.GetKeyDown(KeyCode.Y)){
         Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
         RaycastHit hit;
         if(Physics.Raycast(ray, out hit)){
            PsoftBody hitBody = hit.transform.GetComponent<PsoftBody>();
            if(hitBody)
               hitBody.DeformAtPoint(hit.point, hit.normal, 35f, 0.7f);

and here is my code, (please forgive my ignorance, but I'm trying,)


Orjax

  • Playmaker Newbie
  • *
  • Posts: 21
  • Father/son team, self taught, love learning
I emailed the creator and he was very prompt, but doesn't know playmaker.

He sent this back, (I added the .value to fix the errors)

I want a touch to call deformpoint at the touch point,  but can not get the variables right. 
Here is his code,  close, but I need to get the touch point, I tried saving as a vector3 but i'm off somewhere.

{

    [ActionCategory(ActionCategory.Transform)]
    public class DeformActionPsoftbody : FsmStateAction
    {
        public FsmVector3 screenPos;
        public FsmFloat impactForce;
        public FsmFloat impactScale;

        // Code that runs on entering the state.
        public override void OnEnter()
        {
            Ray ray = Camera.main.ScreenPointToRay(screenPos.Value);
            RaycastHit hit;
            if (Physics.Raycast(ray, out hit))
            {
                PsoftBody hitBody = hit.transform.GetComponent<PsoftBody>();
                if (hitBody)
                    hitBody.DeformAtPoint(hit.point, hit.normal, impactForce.Value, impactScale.Value);
            }
            Finish();
        }
    }
}

thank you for any help. :-[

Anthony

tcmeric

  • Beta Group
  • Hero Member
  • *
  • Posts: 768
Sorry, its hard to debug without the package. However, why not get the ray from the playmaker action "mouse pick event". I wouldnt try and call it in the custom action.

Basically all you want to call in the script is this
"hitBody.DeformAtPoint(hit.point, hit.normal, impactForce.Value, impactScale.Value);"

Ill post an example in a minute.

tcmeric

  • Beta Group
  • Hero Member
  • *
  • Posts: 768
So make sure to enter the correct namespace at the top of this script. Hopefully this should work or be very close (sorry, i cannot debug because I dont have your script). Get the hit normal, etc from the mouse pick event. Only trigger this action from a "mouse click" event (or however you want to trigger it).
Code: [Select]
using UnityEngine;
using _NameSpaceHere;

namespace HutongGames.PlayMaker.Actions
{
    [ActionCategory("Custom")]
    [Tooltip("Description Here.")]

public class deformPsoftBody : FsmStateAction

    {
       
// Game object variable, this is the object with the script attached.

[RequiredField]
[CheckForComponent(typeof(PsoftBody))]
[Tooltip("Game object with the psoft body script attached")]
        public FsmOwnerDefault gameObject;


// Public Variables for Playmaker

public FsmFloat impactForce;
public FsmFloat impactScale;
public FsmVector3 hitNormal;
public FsmVector3 hitPoint;

// setup the script

PsoftBody script;

// have an everyframe option, in case you need to call it everyframe.

public FsmBool everyFrame;

// null out your variables on reset

        public override void Reset()
        {

impactForce = null;
impactScale = null;
hitPoint = null;
hitNormal = null;
everyFrame = false;
        }

// don't run the whole thing inside enter, but instead just initalize and then call your own method below (called make it so).

        public override void OnEnter()
        {
           

// setup the gameobject
var go = Fsm.GetOwnerDefaultTarget(gameObject);
script = go.GetComponent<PsoftBody>();


            if (!everyFrame.Value)
            {
                MakeItSo();
                Finish();
            }

        }

       
// If everyframe variable is set to true, call this everyframe
public override void OnUpdate()
        {
            if (everyFrame.Value)
            {
                MakeItSo();
            }
        }


        void MakeItSo()
        {
            var go = Fsm.GetOwnerDefaultTarget(gameObject);
            if (go == null)
            {
                return;
            }

// Call the method and pass it the values from your variables

script.DeformAtPoint (hitPoint.Value, hitNormal.Value, impactForce.Value, impactScale.Value);

}

     }

}



tcmeric

  • Beta Group
  • Hero Member
  • *
  • Posts: 768
Script attached.

Orjax

  • Playmaker Newbie
  • *
  • Posts: 21
  • Father/son team, self taught, love learning
thank you tcmeric for your reply,  I messed around with it a lot and couldn't get it to work.  I ended up making a code that worked and just put it on the GameObject.
I am very happy that I could write(mostly copy and paste) some code and get it to work.

here is the code that I put on the GO.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Antdeform : MonoBehaviour
{

    // Use this for initialization
    void Start()
    {
        //psoftBodies = Object.FindObjectsOfType<PsoftBody>();

    }

    // Update is called once per frame
    void Update()
    {

        if (Input.touchCount > 0)
        {
            //var screenPos = (Input.GetTouch(0).position);


        }

        {
            Vector3 screenPos = (Input.GetTouch(0).position);
            Ray ray = Camera.main.ScreenPointToRay(screenPos);
            RaycastHit hit;

            if (Physics.Raycast(ray, out hit));
            {
                PsoftBody hitBody = hit.transform.GetComponent<PsoftBody>();
                if (hitBody)
                    hitBody.DeformAtPoint(hit.point, hit.normal, 35f, 0.7f);
                else if (hitBody)
               hitBody.DeformAtPoint(hit.point, hit.normal, 35f, 0.7f);
            }
        }
    }
}


Then I made a PM action to reset the deform, and it worked..

using UnityEngine;

namespace HutongGames.PlayMaker.Actions
{

[ActionCategory(ActionCategory.Transform)]
[Tooltip("resets shape")]
public class psoftBodyReset : FsmStateAction
{
        public PsoftBody  PsoftComponentOwner;
        //public FsmOwnerDefault gameObject;
        void Start()
        {

        }
           
        // Code that runs on entering the state.
        public override void OnEnter()
   {
             PsoftComponentOwner.ResetMesh();
            Finish();
   }
  }

}


(Very simple but I am learning a lot) 
I still would like the "deform" script in an action  bc I want to play with using a touch move delta as a vector3 to deform. Going to keep trying but if anyone could turn the working deform script into an action that would be awesome. 

thanks again and I LOVE this forum, Unity3d, and Playmaker!!  So much fun. :-)

Orjax

  • Playmaker Newbie
  • *
  • Posts: 21
  • Father/son team, self taught, love learning
Sorry, I should have erased the comments //  but I used that a lot to void code without deleting it.  Sorry, makes it kinda hard to read.

Orjax

  • Playmaker Newbie
  • *
  • Posts: 21
  • Father/son team, self taught, love learning
sorry, this is turning out to be more code than I thought, I will move thread if you want.

I am trying to get a new raycast from hit point in the Touch.phase.moved.delta
direction.  I did it this way, but not working. 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Antdragdeform : MonoBehaviour {

    // Use this for initialization
    void Start()
    {
       

    }
    public Vector2 stretch;
    // Update is called once per frame
    void Update()
    {

        if (Input.touchCount > 0)
        {

            Vector3 screenPos = (Input.GetTouch(0).position);
            Ray ray = Camera.main.ScreenPointToRay(screenPos);
            RaycastHit hit;

            if (Input.GetTouch(0).phase == TouchPhase.Began) ;

            if (Physics.Raycast(ray, out hit)) ;
            {
                PsoftBody hitBody = hit.transform.GetComponent<PsoftBody>();
                if (hitBody)
                    hitBody.DeformAtPoint(hit.point, hit.normal, 35f, 0.7f);
                else if (hitBody)
                    hitBody.DeformAtPoint(hit.point, hit.normal, 35f, 0.7f);

            }
            if (Input.GetTouch(0).phase == TouchPhase.Moved) ;
            {

                Vector3 direction = Input.GetTouch(0).deltaPosition;
             
                Physics.Raycast(hit.point, direction);



                {
                    PsoftBody hitBody = hit.transform.GetComponent<PsoftBody>();
                    if (hitBody)
                        hitBody.DeformAtPoint(hit.point, hit.normal, 35f, 0.7f);
                    else if (hitBody)
                        hitBody.DeformAtPoint(hit.point, hit.normal, 35f, 0.7f);
                }

            }

        }
    }
}

tcmeric

  • Beta Group
  • Hero Member
  • *
  • Posts: 768
Its going to be very hard to debug your code. We have neither the source, nor the ability to see your debug logs. It might be best served sending it to the asset creator in this case.