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.
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"
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.