1 (edited by immortalfray 2016-08-26 00:00:14)

Topic: [Tutorial] Temporary power up during fight.

[media]https://www.youtube.com/watch?v=_MHd7PSP4wA[/media]

this is a lengthy process because up until now I've been coding up games from scratch.  Im not used to searching through an experienced programmers code, but it was an amazing learning experience.

*Important*before working on the code for this feature, I implemented the mirror particles mod and weapon trails mod.  So you'll want to add those before attempting to do this.

Here Ill share with you how I was able to implement a temporary transformation to power up a character during a fight.  In the video above Goku can go Super Sayan Blue for the duration of the particle effect, then revert back.  The character has two skinned meshes rigged to the same skeleton.

http://i.imgur.com/AywgMOO.png

Once you have your character rigged and imported then you can proceed with the code.

first open MoveSetScript.CS and look for the public class ParticleInfo and make it look like this

[System.Serializable]
public class ParticleInfo:ICloneable {
    public bool editorToggle;
    public GameObject prefab;
    public float duration = 1;
    public bool stick = false;
    public Vector3 offSet;
    public bool transformed = false;
    public BodyPart bodyPart;
    // X-Weapon Trail support
    public bool isWeaponTrail;
    public bool mirrorOn2PSide;
    public BodyPart bodyPartEnd;  // This is X-Weapon's EndPoint; bodypart is StartPoint
    
    public object Clone() {
        return CloneObject.Clone(this);
    }
}

*again I stress that I implemented mirror particles and weapon trails mods first*

next open MoveEditorWindow.CS and around lines 1821 - 1890 look for

 for (int i = 0; i < moveInfo.particleEffects.Length; i++)
 {}

and after

 moveInfo.particleEffects[i].particleEffect.isWeaponTrail = EditorGUILayout.Toggle("X Weapon Trail:", moveInfo.particleEffects[i].particleEffect.isWeaponTrail, toggleStyle);

make the if else block look like this.  The else part is where I added the toggle for the transformation during a particle effect which we added in MoveSetScript.CS

 if (moveInfo.particleEffects[i].particleEffect.isWeaponTrail)
                                {

                                    moveInfo.particleEffects[i].particleEffect.prefab = (GameObject)EditorGUILayout.ObjectField("X-Weapon Trail Prefab:", moveInfo.particleEffects[i].particleEffect.prefab, typeof(UnityEngine.GameObject), true);
                                    moveInfo.particleEffects[i].particleEffect.duration = EditorGUILayout.FloatField("Duration (seconds):", moveInfo.particleEffects[i].particleEffect.duration);
                                    EditorGUI.BeginDisabledGroup(moveInfo.particleEffects[i].particleEffect.isWeaponTrail);
                                    {
                                        moveInfo.particleEffects[i].particleEffect.stick = EditorGUILayout.Toggle("Sticky", true, toggleStyle);
                                    }
                                    EditorGUI.EndDisabledGroup();
                                    moveInfo.particleEffects[i].particleEffect.bodyPart = (BodyPart)EditorGUILayout.EnumPopup("Inner Point:", moveInfo.particleEffects[i].particleEffect.bodyPart, enumStyle);
                                    moveInfo.particleEffects[i].particleEffect.bodyPartEnd = (BodyPart)EditorGUILayout.EnumPopup("Outer Point:", moveInfo.particleEffects[i].particleEffect.bodyPartEnd, enumStyle);

                                }
                                else {
                                    moveInfo.particleEffects[i].particleEffect.transformed = EditorGUILayout.Toggle("Power Up", moveInfo.particleEffects[i].particleEffect.transformed, toggleStyle);
                                    moveInfo.particleEffects[i].particleEffect.mirrorOn2PSide = EditorGUILayout.Toggle("Mirror on Right Side:", moveInfo.particleEffects[i].particleEffect.mirrorOn2PSide, toggleStyle);
                                    moveInfo.particleEffects[i].particleEffect.prefab = (GameObject)EditorGUILayout.ObjectField("Particle Effect:", moveInfo.particleEffects[i].particleEffect.prefab, typeof(UnityEngine.GameObject), true);
                                    moveInfo.particleEffects[i].particleEffect.duration = EditorGUILayout.FloatField("Duration (seconds):", moveInfo.particleEffects[i].particleEffect.duration);
                                    moveInfo.particleEffects[i].particleEffect.stick = EditorGUILayout.Toggle("Sticky", moveInfo.particleEffects[i].particleEffect.stick, toggleStyle);
                                    moveInfo.particleEffects[i].particleEffect.bodyPart = (BodyPart)EditorGUILayout.EnumPopup("Body Part:", moveInfo.particleEffects[i].particleEffect.bodyPart, enumStyle);
                                    moveInfo.particleEffects[i].particleEffect.offSet = EditorGUILayout.Vector3Field("Off Set (relative):", moveInfo.particleEffects[i].particleEffect.offSet);
                                }

next you'll want to open ControlScript.CS and add these variables to the bottom of the variable declarations, or wherever you want.  Name them differently if you want, I'm not the best at naming conventions but i get by.

 public bool tranformed = false;
    public float transformedOpponentDamageModifier = 2f;

then inside ControlScript.CS, inside of the ReadMove functionlook after line 1195 look for

  // Check Particle Effects
        foreach (MoveParticleEffect particleEffect in move.particleEffects)

inside of this loop look for

StopParticleDelay spComp = pTemp.GetComponent<StopParticleDelay>();

and add these lines after that

 if (particleEffect.particleEffect.transformed == true)
                {
                   // print("Ima Super Sayan!");
                    tranformed = true;
                    myPhysicsScript.transformationDuratrion = particleEffect.particleEffect.duration;
                }
                else{ tranformed = false; }

next while were still inside ControlScript.CS go to the function

private bool DamageMe(float damage){}

and replace this line of code

 myInfo.currentLifePoints -= damage;

with these lines

 if (opPhysicsScript.transrofmed)
        {
            myInfo.currentLifePoints -= damage * transformedOpponentDamageModifier;
        }
        else
        {
            myInfo.currentLifePoints -= damage;
        }

next you want to open PhysicsScript.CS and add these variables at the bottom of the variable declarations again.

 
public bool transrofmed = false;
public float transformationDuratrion = 5f;
[HideInInspector]
 public float transformationSPeed = 1.5f;
 [HideInInspector]
 public float transformationJumpForce = 1.25f;
[SerializeField]
private SkinSwitch skinSwitch;

SkinSwitch is a script I wrote to help me switch between skinned mesh renderers using PhysicsScript.CS, but well get to that at the end.  Once you've added those variables go into the Start function of PhysicsScript and add this line at the top

 skinSwitch = GetComponentInChildren<SkinSwitch>();

then, you'll want to add a void Update(){} function right after the Start function and make it look like this

void Update()
    {
        
        if (myControlsScript.tranformed == true)
        {
            transrofmed = true;
        }
        if (transrofmed)
        {
            transformationDuratrion -= Time.deltaTime;
            skinSwitch.letsSwitch = 1;
            if (transformationDuratrion <= 0f)
            {
                transrofmed = false;
                skinSwitch.letsSwitch = 0;
            }
        }
  

        if ( transformationDuratrion <= 0f)
        {
            //transformationDuratrion = 5f;
            transrofmed = false;
            //print("No Longer a Su per Sayan");
            skinSwitch.letsSwitch = 0;
        }
    }

if you get some errors about the SkinSwitch variables not existing in the current contest, its because we havent created that script yet, but we will so be calm.  *sigh* were almost done lol.

next you'll want to go into the Move function of PhysicsScript.CS and make it look like this

public void Move(int mirror, float direction){
        if (!IsGrounded()) return;
        if (freeze) return;
        if (isTakingOff) return;
        if (isLanding) return;

        if (UFE.config.inputOptions.forceDigitalInput) direction = direction < 0? -1: 1;

        moveDirection = direction;

        if (mirror == 1){
            if (transrofmed)
            {
                //print("Im moving faster");
                myControlsScript.currentSubState = SubStates.MovingForward;
                myControlsScript.horizontalForce = horizontalForce = myControlsScript.myInfo.physics.moveForwardSpeed * (transformationSPeed * direction);
            }
            else
            {
                myControlsScript.currentSubState = SubStates.MovingForward;
                myControlsScript.horizontalForce = horizontalForce = myControlsScript.myInfo.physics.moveForwardSpeed * direction;
            }
        }else{
            if (transrofmed)
            {
                myControlsScript.currentSubState = SubStates.MovingBack;
                myControlsScript.horizontalForce = horizontalForce = myControlsScript.myInfo.physics.moveBackSpeed * (transformationSPeed * direction);
            }
            else
            {
                myControlsScript.currentSubState = SubStates.MovingBack;
                myControlsScript.horizontalForce = horizontalForce = myControlsScript.myInfo.physics.moveBackSpeed * direction;
            }
        }
    }

then you go into the Jump function of PhysicsScript.CS and make it look like this

public void Jump(){
        if (isTakingOff && currentAirJumps > 0) return;
        if (myControlsScript.currentMove != null) return;

        isTakingOff = false;
        isLanding = false;
        myControlsScript.storedMove = null;
        myControlsScript.potentialBlock = false;

        if (myControlsScript.currentState == PossibleStates.Down) return;
        if (myControlsScript.currentSubState == SubStates.Stunned || myControlsScript.currentSubState == SubStates.Blocking) return;
        if (currentAirJumps >= myControlsScript.myInfo.physics.multiJumps) return;
        currentAirJumps ++;
        
        setVerticalData(myControlsScript.myInfo.physics.jumpForce);
        ApplyForces(myControlsScript.currentMove);
        if (transrofmed)
        {
            horizontalForce = myControlsScript.myInfo.physics.jumpDistance * (moveDirection * transformationSPeed);
            verticalForce = (myControlsScript.myInfo.physics.jumpForce) * transformationJumpForce;
        }
        else
        {
            horizontalForce = myControlsScript.myInfo.physics.jumpDistance * moveDirection;
            verticalForce = myControlsScript.myInfo.physics.jumpForce;
        }
    }

ok so the last part for the code involves creating the SkinSwitch.CS script and attaching it to you chracters prefab.  The prefab that has the HitBoxScript.CS attached to it.  Create a new script called SkinSwitch.CS and add this code inside of the newly created script.

using UnityEngine;
using System.Collections;

public class SkinSwitch : MonoBehaviour {
    [SerializeField]
    private SkinnedMeshRenderer original;
    [SerializeField]
    private SkinnedMeshRenderer transformed;
    public int letsSwitch;

    [SerializeField]
    private Transform[] Bodies;
    
    // Use this for initialization
    void Start () {
       
        Bodies = GetComponentsInChildren<Transform>();
        
        foreach (Transform skin in Bodies)
        {
            if (skin.gameObject.name == "OriginalBody")
            {
                original = skin.GetComponent<SkinnedMeshRenderer>();
            }
            if (skin.gameObject.name == "SuperBody")
            {
                transformed = skin.GetComponent<SkinnedMeshRenderer>();
            }
        }
    }
    
    // Update is called once per frame
    void Update () {
        switch (letsSwitch)
        {
            case 0:
                original.enabled = true;
                transformed.enabled = false;
                break;
            case 1:
                original.enabled = false;
                transformed.enabled = true;
                break;
        }
    }
}

for SkinSwitch.CS to work properly, you'll have to name your characters non transformed skinned mesh to "OriginalBody" and the transformed skinned mesh to "SuperBody"

http://i.imgur.com/WjwdrmF.png

Thats pretty much it!  press play and test it out.  Feel free to comment with any tips on how to improve this process.  Obviously with more time spent on this I could add more features to transformation to make it more interesting.  For this little portfolio game I'm workin on its pretty much all that I need.  Right now Im redoing the artwork for Immortal Fray and when I implement this feature it will be tweaked more.

Re: [Tutorial] Temporary power up during fight.

im having trouble with the control script portion on the code im not sure where to input the code at

Share

Thumbs up Thumbs down

3 (edited by immortalfray 2016-09-13 18:18:50)

Re: [Tutorial] Temporary power up during fight.

shannonrattler33 wrote:

im having trouble with the control script portion on the code im not sure where to input the code at

Ok so where in the ControlScript.cs part are you stuck.  Im assuming you've created the variables at least in that script, which should go at the bottom of the variable declarations.  the image below shows where I put them in my project.
http://i.imgur.com/Pdxpz65.png

the next step as mentioned in the tutorial is to go into the ReadMove function which looks like this http://i.imgur.com/qwA8utm.png.

Remember that I mentioned that I implemented the weapon trails mod and the mirror particle effects mod before doing this. 

Also, if you can't see the line numbers in your code environment, I would look up how to make them visible.  It makes tracing through code much easier.

Re: [Tutorial] Temporary power up during fight.

woukld thius still work for the 1.8 update

Share

Thumbs up Thumbs down

Re: [Tutorial] Temporary power up during fight.

Yeah, I dont see why it wouldnt.   Since theyre adding stance switches witha duration (gauge drain), Ill be updating this tutorial to just have the meshes switch in between stances rather than using the particle effect system.

Re: [Tutorial] Temporary power up during fight.

immortalfray wrote:

Yeah, I dont see why it wouldnt.   Since theyre adding stance switches witha duration (gauge drain), Ill be updating this tutorial to just have the meshes switch in between stances rather than using the particle effect system.

Looking forward to it smile

Share

Thumbs up +1 Thumbs down

Re: [Tutorial] Temporary power up during fight.

Hello teacher, I ask you a question: are they two characters? Or are they just two hairs and one is hidden when transformed

Share

Thumbs up Thumbs down