Search Unity

Motion Controller

Discussion in 'Assets and Asset Store' started by Tryz, Feb 21, 2014.

  1. AdminArdagor

    AdminArdagor

    Joined:
    Feb 6, 2018
    Posts:
    11
    Thank Tryz ! With Animator Layer = 1 works ! But I discovered another problem : when I start in game mode in attack styles, i remain only two styles (Forward Slash and Back Slash), and I have to press the Reset button each time - only then the rest (specified by me - Spin Slash, Low Forward Slash ...) attack styles appear. How can I fix this?
     
  2. Salja

    Salja

    Joined:
    Mar 23, 2017
    Posts:
    322
    Hi everybody, I was a bit bored and I thought that I would create a small RPG system for ootii, but now I'm wondering if anyone really needs it, it's not finished yet and it still takes some time but here's an example. Of course, it will be possible to show an effect on the level as well as a sound. Let me know if something is needed or rather I do not want to spend a lot of time to create it. Maybe you also have other ideas what you could install, currently you get XP if you kill an Enemy.

     
    Tryz and Subliminum like this.
  3. mandisaw

    mandisaw

    Joined:
    Jan 4, 2018
    Posts:
    15
    Thanks for this, it's been very timely as I've just about finished my Adventure Creator-MC integration. I hadn't tested the pause function yet, so this has saved me bug-tracking time preemptively :)

    I would add that AdvCreator offers Event support (OnEnterGameState & OnExitGameState), so I'd recommend that any units that need to support pause should subscribe to those events in OnEnable (and unsubscribe in OnDisable).

    Tim, if the Discord thing works out, can you CC any useful snippets back here? Poking back through the forums is a lot more accessible than keeping up on Discord.
     
    Tryz likes this.
  4. TeagansDad

    TeagansDad

    Joined:
    Nov 17, 2012
    Posts:
    770
    It's most likely that any useful snippets will be added to the online documentation, rather than here.

    Speaking from personal experience, I always find it difficult to locate info in a forum thread once it's more than a few pages back. IMO Discord's search feature works better, plus we can split the general support channel into multiple more focused channels as time goes on, if it will keep things better organized.

    I'll certainly try to keep the online docs updated as we continue support discussions on Discord (and here). :)
     
    Tryz, Subliminum and mandisaw like this.
  5. mandisaw

    mandisaw

    Joined:
    Jan 4, 2018
    Posts:
    15
    I usually just use Google for forum-search (& StackOverflow) if I don't find something in the docs, and Discord doesn't surface its content for public search AFAIK.

    But nothing lost by adding Discord to my search habits. Thanks again!
     
    Tryz likes this.
  6. Tryz

    Tryz

    Joined:
    Apr 22, 2013
    Posts:
    3,222
    It sounds like the weapon is rewriting the attack styles. That is a feature that allows you to have different styles for different weapons.

    I can't get to my computer, but maybe this will help: https://ootiigames.com/?page_id=1292

    @TeagansDad might have more insight too.
     
  7. kyonuizanagi

    kyonuizanagi

    Joined:
    Sep 20, 2017
    Posts:
    2
    Hello, I'm new to the motion controllers and have spent the last couple weeks researching which ones would suit my needs best. I found that his one might be the best due to its customizable animations (and the videos that show how to do that--thank you!!), but I had a couple questions:

    1. Is there a better video going over the climbing this controller offers? I saw one where it just grabs the ledges and that's about it, and that video was from 2014, and another one from 2016 that looks better but still just shows the same thing.
    1a. For example, what happens when you grab a ledge and there's nowhere to place your feet?
    1b. Can you increase the distance at which you jump from ledge to ledge?

    2. Can this controller achieve "Breath of the Wild" style movement and combat, including combination attacks?

    3. How many different animations can a single character have before there's a performance problem with this controller?

    Otherwise if looks fantastic and am ready to make my purchase, just want to make sure it can do everything I want. Thanks for your time.
     
  8. TeagansDad

    TeagansDad

    Joined:
    Nov 17, 2012
    Posts:
    770
    I'm not aware of other videos, but you can have a look at the Web Demo for Motion Controller. You'll need to press "Next Scene" once to get to the Climbing scene once the demo loads. Note that the demo is only for Motion Controller -- the basic cameras included with it don't handle collisions, for example, so the camera will pass through walls and obstacles in the web demo. Camera Controller provides that as well as a very flexible solution for dynamically changing camera behaviours during gameplay.

    The basic climbing motions have the character stepping up or pulling up to heights of approximately 0.5m, 1m, 1.8m, and 2.5m; you can try these out on the thing that looks like a big staircase:

    upload_2019-3-29_9-53-11.png

    There's also ladder climbing:

    upload_2019-3-29_9-53-48.png

    Wall climbing allows the player to climb up and down a 90 degree surface (but no side-to-side movement):

    upload_2019-3-29_9-54-30.png

    Ledge climbing has the character grab a ledge and while hanging from it either move side-to-side or pull up to the top:

    upload_2019-3-29_9-55-37.png

    Those are the climbing motions included with Motion Controller. The 2016 video (Hallow's Deep Climbing Alpha 1) was for a more advanced climbing system that @Tryz was working on for his game and has since been released as a free (and unsupported) add-on, available at the Motion Vault.

    If you're looking for a freestyle climbing system like the one that you see in BotW, then you would need to expand upon the included climbing motions with your own code. Motion Controller would definitely able to achieve that sort of climbing movement, but not out-of-the-box.

    BotW style combat is more easily achieved. The Sword & Shield Motion Pack provides the framework for melee combat, including target-locking (while you strafe around the target) and combo attacks. It's built to use the free sword and shield animations available from Mixamo by default, but you can incorporate other animation sets without having to write any code. If you decide to go with Motion Controller, I've built motion packs for Kubold's Sword Animset Pro, Sword and Shield Animset Pro, and Longsword Animset Pro that extend the official Sword & Shield Motion Pack. These animations are much more fluid than the Mixamo ones and just using them instead of the Mixamo animations makes a very big difference as to how the combat "feels" when playing.

    I've never run into any issues. :)

    This is the list of motions on a character in the project I'm currently working on:

    upload_2019-3-29_10-27-18.png

    The Basic Idle, Walk Run Pivot, Walk Run Strafe, Dodge, Damaged, and Death motions have complete animation sets for unarmed (male and female), sword & shield, archery, one-handed sword, longsword, and two-handed melee. Basic Melee Attack has complete animation sets for all of the melee weapons I just listed.

    That's all on the first Motion Layer, which controls the base layer of the animator controller. There's also a smaller number of motions and animations set up to control masked animator layers for the upper body, arms, and hands (as well as an additive blended upper body masked layer needed to control the shield position for Kubold's Sword and Shield Animset Pro animations).

    I've been working with setups like this for a couple of years, and I've never noticed any impact on performance.
     
  9. kyonuizanagi

    kyonuizanagi

    Joined:
    Sep 20, 2017
    Posts:
    2
    Wow, thank you for such a detailed response! I really appreciate it. I tried the web demo and wasn't that impressed with the "animated" climbing (I'm more for climbing that you control), but otherwise looks nice--looks like I will need to supplement with my own climbing options...

    As for the combat, it does look like it will accomplish what I am looking for, only that I will need to find some animations that I am happy with.

    Again, thank you for assisting me in this--I think I will be able to purchase this, but need to study other options for add-on specific functions.
     
    Tryz and TeagansDad like this.
  10. peeka

    peeka

    Joined:
    Dec 3, 2014
    Posts:
    29
    Hi can anyone elaborate the release note : "Support for global serialization" mean?

    I know I ran into a annoying issue with adding variable to Motion, it has a custom json seralization code that only support some basic types.

    I wanted to serialize stuff like AnimationCurve or list but had to write my own custom serializer.

    does global mean it will serialize with anything now?
     
    Subliminum likes this.
  11. TeagansDad

    TeagansDad

    Joined:
    Nov 17, 2012
    Posts:
    770
    @peeka - When running on the .NET 4 runtime, float values were not serializing correctly when the computer's locale settings were set to a region which uses a comma as the decimal separator. That's what the "global" refers to.

    It's a probably stop-gap solution; as you stated, the custom serializer has some serious limitations. Replacing it with something more robust would be desirable.
     
    Tryz likes this.
  12. Tryz

    Tryz

    Joined:
    Apr 22, 2013
    Posts:
    3,222
    Unfortunately, no.

    As @TeagansDad mentioned, the goal was serialization that would work globally with .NET 4. Everything worked fine globally with .NET 3.x, but with .NET 4 it had to change.

    The kind of serializer your talking about ends up being a full asset in itself. The big reason is Unity's lack of support for consistent object IDs and references. The MC typically hasn't needed that level of serialization. I have done some work on extending the serialization, but it still wouldn't be 'everything everywhere'.
     
    Subliminum likes this.
  13. Salja

    Salja

    Joined:
    Mar 23, 2017
    Posts:
    322

    Attached Files:

    Last edited: Apr 1, 2019
  14. dnaloco

    dnaloco

    Joined:
    Mar 31, 2018
    Posts:
    2
    To check if Animator already has some Phase(it's going to show on console):

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3. using UnityEditor.Animations;
    4. using UnityEngine.UI;
    5. using System.Collections.Generic;
    6.  
    7. public class CheckAnimator : EditorWindow
    8. {
    9.     private AnimatorController ac;
    10.     private int motionPhaseID;
    11.     private string[] options;
    12.     private int selected = 0;
    13.     private int numLayers;
    14.     private bool checkInsideEachSubstate;
    15.     private bool checkForm;
    16.     private bool checkStance;
    17.     private bool checkParameter;
    18.  
    19.     [MenuItem("Tools/Animator")]
    20.     public static void ShowWindow()
    21.     {
    22.         //Show existing window instance. If one doesn't exist, make one.
    23.         EditorWindow.GetWindow(typeof(CheckAnimator));
    24.     }
    25.  
    26.  
    27.     void OnGUI()
    28.     {
    29.         GameObject go = Selection.activeObject as GameObject;
    30.         if (go != null)
    31.         {
    32.             Animator an = go.GetComponent<Animator>();
    33.             if (an != null)
    34.             {
    35.                 ac = an.runtimeAnimatorController as AnimatorController;
    36.  
    37.                 if (ac != null)
    38.                 {
    39.                     EditorGUILayout.LabelField("Orange and Yellow for OUTSIDE");
    40.                     EditorGUILayout.LabelField("Cyan and Magenta for INSIDE");
    41.                     EditorGUILayout.LabelField("RED = When check inside, tells where transition states reside");
    42.  
    43.                     motionPhaseID = EditorGUILayout.IntField("Motion Phase ID: ", motionPhaseID);
    44.  
    45.                     checkInsideEachSubstate = EditorGUILayout.Toggle("Check Inside Substates? ", checkInsideEachSubstate);
    46.  
    47.                     checkForm = EditorGUILayout.Toggle("Check Form? ", checkForm);
    48.                     checkParameter = EditorGUILayout.Toggle("Check Paramete? ", checkParameter);
    49.                     checkStance = EditorGUILayout.Toggle("Check Stance? ", checkStance);
    50.                  
    51.                     numLayers = ac.layers.Length;
    52.  
    53.                     options = new string[numLayers + 1];
    54.  
    55.                     options[0] = "All Layers";
    56.  
    57.                     for (int i = 1; i < options.Length; i++)
    58.                     {
    59.                         options[i] = "Layer " + (i - 1);
    60.                     }
    61.  
    62.                     selected = EditorGUILayout.Popup("Which layer?", selected, options);
    63.  
    64.                     if (GUILayout.Button("Check Animator"))
    65.                     {
    66.                         VerifyMotionPhase();
    67.  
    68.                     }
    69.  
    70.                 }
    71.             }
    72.         }
    73.         //} else
    74.         //{
    75.         //    EditorGUILayout.LabelField("Selectione um 'GameObject' com 'Animator' antes.");
    76.  
    77.         //}
    78.  
    79.     }
    80.  
    81.     List<string> destinationStates = new List<string>();
    82.     void VerifyMotionPhase()
    83.     {
    84.         destinationStates.Clear();
    85.         bool toggle = false;
    86.         if (motionPhaseID > 0)
    87.         {
    88.             foreach (var layer in ac.layers)
    89.             {
    90.  
    91.                 foreach (var transition in layer.stateMachine.anyStateTransitions)
    92.                 {
    93.                     bool hasMotionPhase = false;
    94.                     bool hasForm = false;
    95.                     bool hasStance = false;
    96.                     bool hasParameter = false;
    97.  
    98.                     string color = "";
    99.                     if (toggle) color = "<color=yellow>";
    100.                     else color = "<color=orange>";
    101.  
    102.                     string strLayerParameter = "";
    103.                     string strOption = "";
    104.                     string strMotionPhase = "";
    105.                     string strSubstate = "";
    106.                     string strOrigin = "";
    107.                     string strDestination = "";
    108.                     string strForm = "";
    109.                     string strStance = "";
    110.                     string strParameter = "";
    111.  
    112.                     foreach (var condition in transition.conditions)
    113.                     {
    114.                         if (selected > 0)
    115.                         {
    116.                             string layerParameter = "L" + (selected - 1);
    117.                             layerParameter += "MotionPhase";
    118.  
    119.                             if (condition.parameter.Contains(layerParameter))
    120.                             {
    121.                                 //Debug.Log("condition threshold " + condition.threshold);
    122.                                 if ((int)condition.threshold == motionPhaseID)
    123.                                 {
    124.  
    125.                                     strLayerParameter = color + "LayerParameter: <b>" + layerParameter + "</b></color>";
    126.                                     strOption = color + "Layer Selected: <b>" + options[selected] + "</b></color>";
    127.                                     strMotionPhase = color + "Motion Phase: <b>" + motionPhaseID + "</b></color>";
    128.                                     strDestination = color + "Destination: <b>" + transition.destinationState.name + "</b></color>";
    129.                                     hasMotionPhase = true;
    130.  
    131.                                 }
    132.                             }
    133.  
    134.                             if (checkForm)
    135.                             {
    136.                                 string formParameter = "L" + (selected - 1);
    137.                                 formParameter += "MotionForm";
    138.  
    139.                                 if (condition.parameter.Contains(formParameter))
    140.                                 {
    141.                                     strForm = color + "Form: <b>" + (int)condition.threshold + "</b></color>";
    142.                                     hasForm = true;
    143.                                 }
    144.                             }
    145.  
    146.                             if (checkParameter)
    147.                             {
    148.                                 string paramParameter = "L" + (selected - 1);
    149.                                 paramParameter += "MotionParameter";
    150.  
    151.                                 if (condition.parameter.Contains(paramParameter))
    152.                                 {
    153.                                     strParameter = color + "Parameter: <b>" + (int)condition.threshold + "</b></color>";
    154.                                     hasParameter = true;
    155.                                 }
    156.                             }
    157.  
    158.                             if (checkStance)
    159.                             {
    160.                                 string stanceParameter = "Stance";
    161.  
    162.                                 if (condition.parameter.Contains(stanceParameter))
    163.                                 {
    164.                                     strStance = color + "Stance: <b>" + (int)condition.threshold + "</b></color>";
    165.                                     hasStance = true;
    166.                                 }
    167.                             }
    168.  
    169.  
    170.  
    171.                         }
    172.                         else
    173.                         {
    174.                             for (int i = 0; i < numLayers; i++)
    175.                             {
    176.                                 string layerParameter = "L" + i;
    177.                                 layerParameter += "MotionPhase";
    178.  
    179.  
    180.  
    181.                                 if (condition.parameter.Contains(layerParameter))
    182.                                 {
    183.                                     //Debug.Log("condition threshold " + condition.threshold);
    184.                                     if ((int)condition.threshold == motionPhaseID)
    185.                                     {
    186.  
    187.                                         strLayerParameter = color + "LayerParameter: <b>" + layerParameter + "</b></color>";
    188.                                         strOption = color + "Layer Selected: <b>" + options[i + 1] + "</b></color>";
    189.                                         strMotionPhase = color + "Motion Phase: <b>" + motionPhaseID + "</b></color>";
    190.                                         strDestination = color + "Destination: <b>" + transition.destinationState.name + "</b></color>";
    191.                                         hasMotionPhase = true;
    192.  
    193.                                     }
    194.                                 }
    195.  
    196.                                 if (checkForm)
    197.                                 {
    198.                                     string formParameter = "L" + i;
    199.                                     formParameter += "MotionForm";
    200.  
    201.                                     if (condition.parameter.Contains(formParameter))
    202.                                     {
    203.                                         strForm = color + "Form: <b>" + (int)condition.threshold + "</b></color>";
    204.                                         hasForm = true;
    205.                                     }
    206.                                 }
    207.  
    208.                                 if (checkParameter)
    209.                                 {
    210.                                     string paramParameter = "L" + i;
    211.                                     paramParameter += "MotionParameter";
    212.  
    213.                                     if (condition.parameter.Contains(paramParameter))
    214.                                     {
    215.                                         strParameter = color + "Parameter: <b>" + (int)condition.threshold + "</b></color>";
    216.                                         hasParameter = true;
    217.                                     }
    218.                                 }
    219.  
    220.                                 if (checkStance)
    221.                                 {
    222.                                     string stanceParameter = "Stance";
    223.  
    224.                                     if (condition.parameter.Contains(stanceParameter))
    225.                                     {
    226.                                         strStance = color + "Form: <b>" + (int)condition.threshold + "</b></color>";
    227.                                         hasStance = true;
    228.                                     }
    229.                                 }
    230.  
    231.                             }
    232.  
    233.                         }
    234.  
    235.                     }
    236.  
    237.                     if (hasMotionPhase)
    238.                     {
    239.                         Debug.Log(strLayerParameter);
    240.                         Debug.Log(strOption);
    241.                         Debug.Log(strMotionPhase);
    242.  
    243.                         if (checkForm && hasForm)
    244.                         {
    245.                             Debug.Log(strForm);
    246.                         }
    247.                         if (checkParameter && hasParameter)
    248.                         {
    249.                             Debug.Log(strParameter);
    250.                         }
    251.                         if (checkStance && hasStance)
    252.                         {
    253.                             Debug.Log(strStance);
    254.                         }
    255.  
    256.                         Debug.Log(strDestination);
    257.  
    258.                         destinationStates.Add(transition.destinationState.name);
    259.                         toggle = !toggle;
    260.                     }
    261.  
    262.                 }
    263.  
    264.                 if (checkInsideEachSubstate)
    265.                 {
    266.                     foreach (var subState in layer.stateMachine.stateMachines)
    267.                     {
    268.                         foreach (var state in subState.stateMachine.states)
    269.                         {
    270.                             string toRemove = "";
    271.                             bool hasSubstate = false;
    272.                             foreach (string strDest in destinationStates)
    273.                             {
    274.                                 if (strDest == state.state.name && !hasSubstate)
    275.                                 {
    276.                                     toRemove = strDest;
    277.                                     Debug.Log("<color=red><b>!!!DESTINATION STATE <i>" + strDest + "</i> RESIDES INSIDE <i>" + subState.stateMachine.name + "</i> SUBSTATE!!!</b></color>");
    278.                                     hasSubstate = true;
    279.                                 }
    280.                             }
    281.  
    282.                             if(hasSubstate)
    283.                             {
    284.                                 destinationStates.Remove(toRemove);
    285.                                 hasSubstate = false;
    286.                             }
    287.                          
    288.                             foreach (var transition in state.state.transitions)
    289.                             {
    290.                              
    291.                                 bool hasMotionPhase = false;
    292.                                 bool hasForm = false;
    293.                                 bool hasStance = false;
    294.                                 bool hasParameter = false;
    295.  
    296.                                 string color = "";
    297.                                 if (toggle) color = "<color=magenta>";
    298.                                 else color = "<color=cyan>";
    299.  
    300.                                 string strLayerParameter = "";
    301.                                 string strOption = "";
    302.                                 string strMotionPhase = "";
    303.                                 string strSubstate = "";
    304.                                 string strOrigin = "";
    305.                                 string strDestination = "";
    306.                                 string strForm = "";
    307.                                 string strStance = "";
    308.                                 string strParameter = "";
    309.  
    310.                                 foreach (var condition in transition.conditions)
    311.                                 {
    312.                                     if (selected > 0)
    313.                                     {
    314.                                         string layerParameter = "L" + (selected - 1);
    315.                                         layerParameter += "MotionPhase";
    316.  
    317.  
    318.  
    319.                                         if (condition.parameter.Contains(layerParameter))
    320.                                         {
    321.                                             //Debug.Log("condition threshold " + condition.threshold);
    322.                                             if ((int)condition.threshold == motionPhaseID)
    323.                                             {
    324.  
    325.                                                 strLayerParameter = color + "LayerParameter: <b>" + layerParameter + "</b></color>";
    326.                                                 strOption = color + "Layer Selected: <b>" + options[selected] + "</b></color>";
    327.                                                 strMotionPhase = color + "Motion Phase: <b>" + motionPhaseID + "</b></color>";
    328.                                                 strSubstate = color + "Substate : <b>" + subState.stateMachine.name + "</b></color>";
    329.                                                 strOrigin = color + "Origin: <b>" + state.state.name + "</b></color>";
    330.                                                 strDestination = color + "Destination: <b>" + transition.destinationState.name + "</b></color>";
    331.  
    332.                                                 hasMotionPhase = true;
    333.  
    334.                                             }
    335.                                         }
    336.  
    337.                                         if (checkForm)
    338.                                         {
    339.                                             string formParameter = "L" + (selected - 1);
    340.                                             formParameter += "MotionForm";
    341.  
    342.                                             if (condition.parameter.Contains(formParameter))
    343.                                             {
    344.                                                 strForm = color + "Form: <b>" + (int)condition.threshold + "</b></color>";
    345.                                                 hasForm = true;
    346.                                             }
    347.                                         }
    348.  
    349.                                         if (checkParameter)
    350.                                         {
    351.                                             string paramParameter = "L" + (selected - 1);
    352.                                             paramParameter += "MotionParameter";
    353.  
    354.                                             if (condition.parameter.Contains(paramParameter))
    355.                                             {
    356.                                                 strParameter = color + "Parameter: <b>" + (int)condition.threshold + "</b></color>";
    357.                                                 hasParameter = true;
    358.                                             }
    359.                                         }
    360.  
    361.                                         if (checkStance)
    362.                                         {
    363.                                             string stanceParameter = "Stance";
    364.  
    365.                                             if (condition.parameter.Contains(stanceParameter))
    366.                                             {
    367.                                                 strStance = color + "Stance: <b>" + (int)condition.threshold + "</b></color>";
    368.                                                 hasStance = true;
    369.                                             }
    370.                                         }
    371.  
    372.  
    373.  
    374.                                     }
    375.                                     else
    376.                                     {
    377.                                         for (int i = 0; i < numLayers; i++)
    378.                                         {
    379.                                             string layerParameter = "L" + i;
    380.                                             layerParameter += "MotionPhase";
    381.  
    382.  
    383.  
    384.                                             if (condition.parameter.Contains(layerParameter))
    385.                                             {
    386.                                                 //Debug.Log("condition threshold " + condition.threshold);
    387.                                                 if ((int)condition.threshold == motionPhaseID)
    388.                                                 {
    389.  
    390.                                                     strLayerParameter = color + "LayerParameter: <b>" + layerParameter + "</b></color>";
    391.                                                     strOption = color + "Layer Selected: <b>" + options[i + 1] + "</b></color>";
    392.                                                     strMotionPhase = color + "Motion Phase: <b>" + motionPhaseID + "</b></color>";
    393.                                                     strSubstate = color + "Substate : <b>" + subState.stateMachine.name + "</b></color>";
    394.                                                     strOrigin = color + "Origin: <b>" + state.state.name + "</b></color>";
    395.                                                     strDestination = color + "Destination: <b>" + transition.destinationState.name + "</b></color>";
    396.  
    397.                                                     hasMotionPhase = true;
    398.  
    399.                                                 }
    400.                                             }
    401.  
    402.                                             if (checkForm)
    403.                                             {
    404.                                                 string formParameter = "L" + i;
    405.                                                 formParameter += "MotionForm";
    406.  
    407.                                                 if (condition.parameter.Contains(formParameter))
    408.                                                 {
    409.                                                     strForm = color + "Form: <b>" + (int)condition.threshold + "</b></color>";
    410.                                                     hasForm = true;
    411.                                                 }
    412.                                             }
    413.  
    414.                                             if (checkParameter)
    415.                                             {
    416.                                                 string paramParameter = "L" + i;
    417.                                                 paramParameter += "MotionParameter";
    418.  
    419.                                                 if (condition.parameter.Contains(paramParameter))
    420.                                                 {
    421.                                                     strParameter = color + "Parameter: <b>" + (int)condition.threshold + "</b></color>";
    422.                                                     hasParameter = true;
    423.                                                 }
    424.                                             }
    425.  
    426.                                             if (checkStance)
    427.                                             {
    428.                                                 string stanceParameter = "Stance";
    429.  
    430.                                                 if (condition.parameter.Contains(stanceParameter))
    431.                                                 {
    432.                                                     strStance = color + "Form: <b>" + (int)condition.threshold + "</b></color>";
    433.                                                     hasStance = true;
    434.                                                 }
    435.                                             }
    436.  
    437.                                         }
    438.  
    439.                                     }
    440.  
    441.                                 }
    442.  
    443.                                 if (hasMotionPhase)
    444.                                 {
    445.                                     Debug.Log(strLayerParameter);
    446.                                     Debug.Log(strOption);
    447.                                     Debug.Log(strMotionPhase);
    448.  
    449.                                     if (checkForm && hasForm)
    450.                                     {
    451.                                         Debug.Log(strForm);
    452.                                     }
    453.                                     if (checkParameter && hasParameter)
    454.                                     {
    455.                                         Debug.Log(strParameter);
    456.                                     }
    457.                                     if (checkStance && hasStance)
    458.                                     {
    459.                                         Debug.Log(strStance);
    460.                                     }
    461.  
    462.                                     Debug.Log(strSubstate);
    463.                                     Debug.Log(strOrigin);
    464.                                     Debug.Log(strDestination);
    465.                                     toggle = !toggle;
    466.                                 }
    467.  
    468.  
    469.                             }
    470.  
    471.  
    472.                         }
    473.                     }
    474.                 }
    475.             }
    476.         }
    477.     }
    478. }
     
    Last edited: Apr 5, 2019
    Subliminum, Tryz and Salja like this.
  15. pcg

    pcg

    Joined:
    Nov 7, 2010
    Posts:
    200
    Hey Tim,

    I'm using the motion controller along with rewired and I want to be able to freeze the players character (when an enemy casts a spell).
    How would you recommend doing this?

    Currently I'm setting the players animator speed to zero which stops movement & animation as im using root motion, but input still allows the motion controller to be affected such as rotation etc.
     
  16. Tryz

    Tryz

    Joined:
    Apr 22, 2013
    Posts:
    3,222
    Cool effect! :)

    On the input source (probably Unity Input Source component) for your character, set the IsEnabled flag to false when he's frozen. Then, the character won't respond to any input.

    The only thing I think could happen is if you are pressing forward (MovementY = 1) and you set the input source IsEnabled = 0, the MovementY will become 0... that could cause an animation from walk/run to idle. If that happens, you may want to have a custom input source that stores the values you last used in the input source. Then, you'd return the last used value when you "freeze the input". Meaning MovementY returns 1 instead of 0.

    I hope that makes sense.
     
    pcg likes this.
  17. Tryz

    Tryz

    Joined:
    Apr 22, 2013
    Posts:
    3,222
    Salja likes this.
  18. p_hergott

    p_hergott

    Joined:
    May 7, 2018
    Posts:
    202
    With ai. Whats the function to to send to get an ai to attack? And the function to receive damage.
     
  19. Tryz

    Tryz

    Joined:
    Apr 22, 2013
    Posts:
    3,222
    Everything is done through messages.

    To receive damage, you can use a reactor. Reactors allow you to react to incoming messages. So, you can have a custom reactor that receives damage and does whatever you want. I typically use this approach for characters. This way you can intercept the attack and block, dodge, etc.

    Another way to receive damage is to implement my IDamageable interface. It has an OnDamaged() function you can implement. This is a good approach if you want a barrel to break when it's hit. I typically use this approach for simple objects.

    To get an MC character to attack, you can either send a message through the MC or active the specific motion. Here's an example that I use in the Sword & Shield Motion Pack to have the NPC swing his sword.

    Code (CSharp):
    1. CombatMessage lMessage = CombatMessage.Allocate();
    2. lMessage.ID = CombatMessage.MSG_COMBATANT_ATTACK;
    3. lMessage.Attacker = gameObject;
    4. lMessage.Defender = Target.gameObject;
    5.  
    6. mMotionController.SendMessage(lMessage);
    7. CombatMessage.Release(lMessage);
    8.  
    Obviously you'll have to implement these for your AI, but I hope that helps.
     
  20. DBrad

    DBrad

    Joined:
    Jan 16, 2013
    Posts:
    4
    Hi guys!

    Was curious if anyone here has played with multiplayer and if so, would love to chat! Looking for some help here and any would be appreciated :)
     
  21. Jonnywin

    Jonnywin

    Joined:
    Apr 7, 2019
    Posts:
    1
    Hi, I'm wanting to implement a click to move control scheme. I've set up a player character with the actor controller, so I can set a target and have the character move to it using Navmesh. I'm just struggling to figure out how to code that target to be a right mouse click. Any help would be greatly appreciated.

    Expanding on that, any info on modifying the sword/archery/magic packs to work in a top-down RPG manner would be great too.

    Thanks!
     
  22. p_hergott

    p_hergott

    Joined:
    May 7, 2018
    Posts:
    202
    I gotta be missing something, i added dual wield weapons to the sword and shield pack, created a weapon set, gave it a form of 600. Set a equip store idle walks and pivots and attack motions in with form 600. And in playmode, he goes to the right weapon set, he equips the right motions and weapons, he walks and turns right, but doesnt attack. I gotta be missing something small.
     
  23. Subliminum

    Subliminum

    Joined:
    Nov 9, 2017
    Posts:
    71
    Are your weapons using Attack Profiles? If so, you should have a Basic Attack Profile script attached to your prefabs and the Basic Attack Profiles Reactor in your Actor Core. Otherwise you can also create them in the Basic Melee Attack motion too.
    It could also be that you don't have your Input Alias' set up correctly to trigger an attack.
     
  24. manuelgoellnitz

    manuelgoellnitz

    Joined:
    Feb 15, 2017
    Posts:
    8
    Hi,
    We try to get an NPC via NavMesh to a specific transform. All the ootii NavMesh-examples I have seen so far do that, but only to the position.
    We also want that the NPC is turned into the direction of that transform.
    Our idea was to modify NavMeshInputSource to walk the NPC to the Target position and turn on arrival in the right direction.

    We used WalRunPivot since it has aninmations to turn when stationary.
    How do the input values have to be, so that the turning is triggered?
    Our guess was only to set "inputFromCameraAngle" or "viewX". But nothing happens then.

    We got it somehow working wenn Setting "inputFromCameraAngle" and "movementX" for a short time which simulated "tapToPivot", i think.
    But isn't there a better way to do it, because it only worked, when the walking animation was finished and in an inputSource i shouldn't care about that, or not?
     
  25. KeithBrown

    KeithBrown

    Joined:
    Apr 1, 2017
    Posts:
    105
    @manuelgoellnitz The user guide has a small section on the API of the motion controller. http://www.ootii.com/Unity/MotionController/MC2Guide.pdf. On page 30 of the guide it talks about moving and mentions the SetTargetPosition method of the api. I went to the class and poked around and there is a SetTargetRotation method . You should be able to call that method to get your character to rotate using motions.

    Code (CSharp):
    1. /// <summary>
    2. /// Rotates the actor towards the target rotation.
    3. /// </summary>
    4. /// <param name="rPosition"></param>
    5. /// <param name="rNormalizedSpeed"></param>
    6. public void SetTargetRotation(Quaternion rRotation)
    7. {
    8.     _UseSimulatedInput = true;
    9.  
    10.     mTargetRotation = rRotation;
    11.     mIsTargetRotationSet = true;
    12. }
    Alternatively, you can wait for Tryz to chime in or TeagansDad. Tryz usually replies on the weekend. You might try the Discord channel also.
     
    Tryz likes this.
  26. p_hergott

    p_hergott

    Joined:
    May 7, 2018
    Posts:
    202
    Oh geez, i forgot all about the profile scipts.... haha thx
     
  27. TeagansDad

    TeagansDad

    Joined:
    Nov 17, 2012
    Posts:
    770
    You'll need to perform a raycast to the walkable area to get the navigation target. The Unity docs provide a simple example of how to do this:

    Code (CSharp):
    1. // MoveToClickPoint.cs
    2.     using UnityEngine;
    3.     using UnityEngine.AI;
    4.    
    5.     public class MoveToClickPoint : MonoBehaviour {
    6.         NavMeshAgent agent;
    7.        
    8.         void Start() {
    9.             agent = GetComponent<NavMeshAgent>();
    10.         }
    11.        
    12.         void Update() {
    13.             if (Input.GetMouseButtonDown(0)) {
    14.                 RaycastHit hit;
    15.                
    16.                 if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit, 100)) {
    17.                     agent.destination = hit.point;
    18.                 }
    19.             }
    20.         }
    21.     }
    The example uses the left button (0); you can just change that to the right button (1) or better yet, add a public int field so you can configure it in the inspector.

    This simple version doesn't check layers and doesn't handle holding the button down as you move the mouse, but it's enough to get you started.

    I have a more advanced click to move script somewhere that uses the NavMeshInputSource to produce better looking movement, but it's on the secondary drive of my old laptop that failed a few weeks ago. I just need to pop the drive out and attach it totmy new laptop via a USB enclosure, but I've been swamped with real life stuff.

    I think that the Sword and Shield pack should work pretty well in a top down perspective (you probably don't want to use the target locking though; at least not without modifying it). Archery will require the most tweaks, as you're probably not going to want the separate "aiming" step and the rate of fire will likely be too slow when you can't see enemies until they are close.
    I think Magic should work well, but you definitely won't want "Release from camera" checked. Targeting an area of effect will probably work better than in the third person perspective.
     
  28. TeagansDad

    TeagansDad

    Joined:
    Nov 17, 2012
    Posts:
    770
    @manuelgoellnitz - I haven't used the older WalkRunPivot motions for quite some time, so memory is a bit fuzzy. I know that I did have something that worked similar to what you're describing... I can't remember if it did the 90 degree idle turns, but it definitely did the 180 turns. It used the NavMeshInputSource and I'm pretty sure it was the same prototype that used the click to move script that I mentioned in my reply directly above this one.

    I'll try and get my data drive from my old laptop removed and connected to my new laptop sometime this weekend. Hopefully I can give you some useful help once I can have called look at it again.
     
  29. Tryz

    Tryz

    Joined:
    Apr 22, 2013
    Posts:
    3,222
    Hi @manuelgoellnitz ,

    Unfortunately, pivoting doesn't exist for NPCs out-of-the-box. However, you can add it with a custom motion.

    The issue with using any of the existing "pivot" motions with NPCs is that the motions use the camera to determine the relative user input and NPCs typically don't have the camera associated with them.

    Here's what I mean...

    Say the character is facing north and the camera (player's view) is facing north, then hitting the 'S' key means the input is 180-degrees from the character's facing direction (North * 'S key' = South). With that, we know the character should do a 180-degree pivot and face south.

    Say the character is facing north, but the camera (player's view) is facing east, then hitting the 'S' key means the input is 90-degrees from the character's facing direction (East * 'S key' = West). With that, we know the character should do a 90-degree pivot and face west.

    So, in my implementation the camera is pretty important with the pivots.You can see that in the WalkRunPivot_v2.UpdateIdlePivot() function at line 695 where I get the input direction using the camera rotation.

    Typically I use the "strafe" motions with NPCs and then turn them to the direction I want in the AI with either MC.SetTargetRotation() as @KeithBrown mentioned or I use the AC.Rotate() function. This allows my PCs to go forward, backwards, sideways, etc. However, I don't have nice pivot animations.

    If you want to use the pivot animations in the "WalkRunPivot v2-SM" state machine, you'd have to create a "pivot" motion that doesn't use the camera, but instead looks purely at desired direction relative to the character. This would be a new motion. I believe you could take something like WalkRunPivot_v2.cs, copy it and clean up the camera parts. With some testing it would get you what you want.
     
  30. bee_frog_rabbit

    bee_frog_rabbit

    Joined:
    Dec 13, 2016
    Posts:
    3
    Hi,
    I purchased both your Camera controller, and then your Third Person Motion Controller. I am running into an issue where the keyboard commands do not respond in WASD. If you are using W to move character forward, pressing A while still holding down W does not work. Basically I would like to turn while moving forward. This seems pretty basic so I am sure I must be missing something obvious. How do I accomplish this?
     
  31. KeithBrown

    KeithBrown

    Joined:
    Apr 1, 2017
    Posts:
    105
    I just tried it on the _demo_Terrain located at ootii/_demos/MotionController/Scenes and it worked fine for me. Did you make sure to click the setup input entries button on the motion controller component?

    I will mention that I also own Easy Input from ootii and not sure if it somehow took control. Its a new project and I have not set it up yet though.
     
    Tryz likes this.
  32. Tryz

    Tryz

    Joined:
    Apr 22, 2013
    Posts:
    3,222
    There's nothing tricky. I even use the default Unity Input Manager entries for movement input: horizontal and vertical. Make sure those exist in Unity's Input Manager. The should automatically.

    As @KeithBrown said, try my demo_Terrain scene. That allows the character to move and turn.

    If you want to email tim@ootii.com your input manager entries, I can look.
     
  33. jreid423

    jreid423

    Joined:
    Jun 27, 2013
    Posts:
    2
    Hi, I have discovered that since the latest Unity 2019.1 update the motion controller is now displaying the following errors -

    Assets\ootii\Assets\Framework_v1\Code\Networking\BasicActorNetworkSync.cs(16,42): error CS0246: The type or namespace name 'NetworkBehaviour' could not be found (are you missing a using directive or an assembly reference?)

    Assets\ootii\Assets\Framework_v1\Code\Networking\BasicActorNetworkSync.cs(15,30): error CS0246: The type or namespace name 'NetworkIdentity' could not be found (are you missing a using directive or an assembly reference?)

    Assets\ootii\Assets\Framework_v1\Code\Networking\BasicActorNetworkSync.cs(126,30): error CS0115: 'BasicActorNetworkSync.PreStartClient()': no suitable method found to override

    Assets\ootii\Assets\Framework_v1\Code\Networking\BasicActorNetworkSync.cs(144,30): error CS0115: 'BasicActorNetworkSync.OnStartClient()': no suitable method found to override

    Assets\ootii\Assets\Framework_v1\Code\Networking\BasicActorNetworkSync.cs(160,30): error CS0115: 'BasicActorNetworkSync.OnStartLocalPlayer()': no suitable method found to override

    Assets\ootii\Assets\Framework_v1\Code\Networking\BasicActorNetworkSync.cs(406,10): error CS0246: The type or namespace name 'CommandAttribute' could not be found (are you missing a using directive or an assembly reference?)

    Assets\ootii\Assets\Framework_v1\Code\Networking\BasicActorNetworkSync.cs(406,10): error CS0246: The type or namespace name 'Command' could not be found (are you missing a using directive or an assembly reference?)

    Assets\ootii\Assets\Framework_v1\Code\Networking\BasicActorNetworkSync.cs(419,10): error CS0246: The type or namespace name 'ClientRpcAttribute' could not be found (are you missing a using directive or an assembly reference?)

    Assets\ootii\Assets\Framework_v1\Code\Networking\BasicActorNetworkSync.cs(419,10): error CS0246: The type or namespace name 'ClientRpc' could not be found (are you missing a using directive or an assembly reference?)
     
  34. Tryz

    Tryz

    Joined:
    Apr 22, 2013
    Posts:
    3,222
    Thanks @jreid423 ,

    Unity 2019.1 removed Unity's support for NetworkBehaviour. So, I've updated the code to not use it in Unity 2019 and above. It's not a major issue as it was an example for network support with Unity's code... which no longer exists.

    I've published the update, but Unity has to review it. It should be out in a couple of hours.

    Until then, you can simply delete the following files:
    BasicActorNetworkSync.cs
    BasicActorNetworkSyncEditor.cs
     
  35. hopeful

    hopeful

    Joined:
    Nov 20, 2013
    Posts:
    4,877
    I gather the free and open source Mirror project is an adaptation and update for Unity's old networking, so if anyone wants to continue using that networking solution, there appears to be a path.
     
    Tryz likes this.
  36. maxray

    maxray

    Joined:
    Aug 26, 2014
    Posts:
    26
    I found the Combatant class events Execution Is Not Implemented,

    How to do it, I want the attacker’s attack motion message send to defender when it activate.
     
  37. maxray

    maxray

    Joined:
    Aug 26, 2014
    Posts:
    26
    And I want to write a custom Reactor to detect the attacker's PreAttack in order to active a dodge action, how to do it
     
  38. Tryz

    Tryz

    Joined:
    Apr 22, 2013
    Posts:
    3,222
    The Combatant only has events for "Target Locked" and "Target Unlocked". For attacks, you'll want to use reactors.

    Check out this documentation on Reactors.

    The message IDs are important as they describe what's happening:
    See Combat Message IDs

    In order for your defender to dodge, you can have the defender react to the "MSG_COMBAT_DEFENDER_ATTACKED" (1150) message. In your code, you would set the ID to 1105 (MSG_COMBAT_DEFENDER_ATTACKED_EVADED).

    That will keep any damage from being applied.

    The documentation for Reactors gives you an example of the code. I hope that helps.
     
  39. luekio

    luekio

    Joined:
    Jan 23, 2018
    Posts:
    21
    Hey Folks, I have been out of action for about 8 months, but I'm about to jump back in. I was wondering if there have been any updates to the climbing system of late?

    I had been previously trying to get an assassins creed/breath of the wild style climb system working in ootti with mixed results.
     
  40. Salja

    Salja

    Joined:
    Mar 23, 2017
    Posts:
    322
    You can download a more advance climb system in the vault

    Screenshot_3.png


    http://www.ootii.com/UnityMotionVault.cshtml
     
    luekio and Tryz like this.
  41. maxray

    maxray

    Joined:
    Aug 26, 2014
    Posts:
    26
    Hi, I have a problem:

    When I add a dodge motion in animator(new blendtree), and I activate the motion when playing, it played the dodge motion but it’s freezing at the motion completion, cant response wsad movement, other actions like attack, block, jump can restore it. How to fix it?
     
  42. Tryz

    Tryz

    Joined:
    Apr 22, 2013
    Posts:
    3,222
    I'm guessing you're not telling the motion to exit. Sometimes I exit motions based on timers, sometimes it's based on the 'tag' of the animator state, sometimes it's when specific action occurs (like a key is released).

    In the TestUpdate() function of your motion, return 'false' when it's time for your motion to end. Otherwise, it will go on for ever.

    In your case, you probably want to add a tag to your animator state. Then, in TestUpdate() check if the animator state has that tag. If it does... return false.

    Check out my Basic Damaged motion (BasicDamanged.cs) at line 114. I do exactly this.
     
    TeagansDad likes this.
  43. TeagansDad

    TeagansDad

    Joined:
    Nov 17, 2012
    Posts:
    770
    Are you using the Basic Dodge motion, or a dodge motion that you created yourself?

    Basic Dodge uses an "Exit" tag on a one-frame idle pose to indicate when the motion should exit (as @Tryz explains above).
     
  44. maxray

    maxray

    Joined:
    Aug 26, 2014
    Posts:
    26
    Yes, I use Basic Dodge motion, and how to add "Exit" tag
     
  45. maxray

    maxray

    Joined:
    Aug 26, 2014
    Posts:
    26
    OK, I know how to do it, thank you all :p
     
    Tryz and TeagansDad like this.
  46. maxray

    maxray

    Joined:
    Aug 26, 2014
    Posts:
    26
    @Tryz, Could you add an official dodge reactor and parry reactor for defender
     
  47. devstudents

    devstudents

    Joined:
    Feb 18, 2014
    Posts:
    132
    Hello. I apologise in advance for the basic question, but after I followed the steps in the pdf for Sword and Shield, everything works except lock-on. I've tried using middle mouse button and 't' -the old lock-on button. Any help would be appreciated :)
     
  48. Salja

    Salja

    Joined:
    Mar 23, 2017
    Posts:
    322
    Try Y
     
    Tryz and devstudents like this.
  49. devstudents

    devstudents

    Joined:
    Feb 18, 2014
    Posts:
    132
    Thanks! Y worked.
     
  50. devstudents

    devstudents

    Joined:
    Feb 18, 2014
    Posts:
    132
    I have another issue now. I'm following the archery tutorial, and the enemies are standing in t-pose, there is no visible crosshair, and the targets do not respond to the arrows. In addition, there is the following error:

    IndexOutOfRangeException: Index was outside the bounds of the array.
    com.ootii.Actors.AnimationControllers.MotionControllerLayer.UpdateMotions (System.Single rDeltaTime, System.Int32 rUpdateIndex) (at Assets/Ootii/Assets/MotionController/Code/Actors/AnimationControllers/MotionController/MotionControllerLayer.cs:436)
    com.ootii.Actors.AnimationControllers.MotionController.OnControllerLateUpdate (com.ootii.Actors.ICharacterController rController, System.Single rDeltaTime, System.Int32 rUpdateIndex) (at Assets/Ootii/Assets/MotionController/Code/Actors/AnimationControllers/MotionController/MotionController.cs:1073)
    com.ootii.Actors.ActorController.InternalUpdate (System.Single rDeltaTime, System.Int32 rUpdateIndex) (at Assets/Ootii/Assets/ActorController/Code/Actors/CharacterControllers/ActorController.cs:1412)
    com.ootii.Actors.ActorController.ControllerLateUpdate (System.Single rDeltaTime, System.Int32 rUpdateIndex) (at Assets/Ootii/Assets/ActorController/Code/Actors/CharacterControllers/ActorController.cs:1371)
    com.ootii.Actors.BaseSystemController.LateUpdate () (at Assets/Ootii/Assets/Framework_v1/Code/Actors/BaseSystemController.cs:264)
    com.ootii.Actors.ActorController.LateUpdate () (at Assets/Ootii/Assets/ActorController/Code/Actors/CharacterControllers/ActorController.cs:1324)

    I'm confident I followed the steps exactly as the Sword and Shield package didn't have this issue. I put the meta files that came with the project into the Mixamo animation folder in the archery folder, and closed and re-opened unity.