Switch state machines on the fly Unity C# - c#

Having a little bit of an issue and cant seem to find an answer anywhere on the internet.
I have 4 sub state machines in Unity (see attached image), and upon play, if defaults to the pistol state machine and plays the idle animation fine.
I want to however have some code where by the user presses M, he can switch to the rifle sub state machine.
I have tried animator.Play but that does not seem to do the trick, so I am bit stuck. The following does not work which i tried:
if(Input.GetKeyDown(KeyCode.M))
{
animator.Play("Rifle",0);
}
Any ideas?

Every Default button in unity has its own 'name' called input axes in which you can call (i.e "fire1","jump")
This could be very useful especially in Mobile applications where you set these buttons to operate each on-screen button in your virtual controller.
If you want to add new virtual axes go to the Edit->Project Settings->Input menu
see here
Here is an example almost similar to your code
var bullet : GameObject;
var shootPoint : Transform;
function Update (){
if(Input.GetKeyDown("Fire1")) || Input.GetKeyDown("space")){
//example
Instantiate(bullet, shootPoint.position, tranform.rotation);
//you could put the code on how you shoot here
}
remember that update is called once every frame
Hope This Helps

You can accomplish this by creating an integer parameter in your Animator. Then in your code, when you want to switch to another one, set the integer to a different value; each transition (white line) is assigned a different integer.
From code:
// in the class
Animator anim; // assign in Awake()
// in a function
if(Input.GetKeyDown(KeyCode.M)) {
anim.SetInteger ("WeaponState", 2); // goes to Rifle
}
To work with this, you could create a None state machine as the default and get rid of Null. You would then have Any State point to None, Pistol, Rifle, etc.

Related

Get VRTK input to set a value inside an animator controller

(I already followed the tutorial 002 from VRTK, to use the custom trigger event on right and left controller. And it do work, but not for what I want.)
I do have a character instanciated from a prefab with his own Animatorcontroller. I attached to him my own "animator script", doing hand gesture when I press the button 0,1,2,3... and it's working and it work like that.
void Update()
{
// LEFT HAND //
if (Input.GetKey(KeyCode.Keypad0))
m_Animator.SetInteger("HandGestureLeft", 0); // FIST
else if (Input.GetKey(KeyCode.Keypad1))
m_Animator.SetInteger("HandGestureLeft", 1); // PALM
else if (Input.GetKey(KeyCode.Keypad2))
m_Animator.SetInteger("HandGestureLeft", 2); // POINT
Now I want to do it from my VR Controller buttons inputs instead of the 0.1.2.3 keypad. And I learnt that VRTK have some functions to do it. So I goes into the "VRTK_ControllerEvents_ListenerExample script" from the 002 example scene and I put the script on the left and right controller (Which are inside the VRTK gameobject scene) (not on my prefab avatar because if I do it nothing work anymore, the 002 scene script must be on the controllers instanciated by VRTK as the tutorial says).
I can put animations inside and have them working. But they only work for my prefab if I put it inside the scene already, and do not instanciate it. So as a player I cannot have my gestures working, because when I hit play I must have my character instanciated for my game to work (And my default script does that well, when I press the 0,1,2,3... key because I do not need to have it on the hand controllers, I can have it on my prefab).
So I have a problem and they may be two solution from what I see.
I may have a call to the VRTK controller functions directly inside my old "animator script". So it could look like :
if (Input.GetKey(KeyCode.Keypad0))
m_Animator.SetInteger("HandGestureLeft", 0); // FIST
into
if (GetComponent().TriggerPressed)==true) (BUT it tell me that TriggerPressed isn't available)
m_Animator.SetInteger("HandGestureLeft", 0); // FIST
(But I have no idea how to grab the VR controller input from where VRTK is listening)
or there could be a way to have a call to my prefab AnimatorController Component inside the "VRTK_ControllerEvents_ListenerExample" script from the left and right controller. But here too, i have no idea how to call the prefab component, I can only call for the AnimatorControllerComponent if I have my Avatar Prefab on the scene already.
Well finally all I could need is the way to check from my prefab script if the leftcontroller or rightcontroller is pressing the trigger. Just like the "Input.GetKey(KeyCode.Keypad0)" but with the VRTK way to get the trigger input instead.
I'm totally lost, could someone help me ? :D
Here two images. Right now my working code look like that :
![1]: https://vrtoolkit.slack.com/files/UA39CMQRF/FA3BD4YD6/code.png "Code0"
![2]: https://vrtoolkit.slack.com/files/UA39CMQRF/FA3BD6DR6/code1.png "Code1"
Alright I found it finally. It was link that :
if(RightHand.GetComponent<VRTK_ControllerEvents>().IsButtonPressed(VRTK_ControllerEvents.ButtonAlias.GripPress) == true)
{
m_Animator.SetInteger("HandGestureLeft", 0);
}

Unity modify animation at runtime

TLDR:
Basically, I use the same animation for all of the soldiers, but I want those animations to behave little different from each other, so all my soldiers won't behave all the same. Would i be able to modify those animation at runtime?
So I'm working on this RTS style game that has a group of soldiers, let's say charging. Since most of them using the same animation. Although I randomize the starting time of each animation, so they won't be played simultaneously. But everybody in the unit is still charging with the same animation. And it looks rather weird.
I wonder if there's a way that I can alter each animation a little bit on runtime, to the degree they swing their arm, for example, one of the soldiers would swing a few degrees more, and other will swing less.
I wonder if it's possible to do in unity at runtime. And if so, how would I do it?
Any suggestions would be appreciated.
First and foremost, replace your animation with animator controller.
Inside the animator, for example, you can add animation events. You can also define animation parameters. Based on the parameters you define, your character can switch between different animations. Lets take a look at an example now.
Put a script, SoldierAnimator, on your soldier that has reference to the animator controller.. Now, lets say that your soldier's 'loadGun' animation has 3 variations. You now assign a parameter to each animation. So 'crouchLoad', 'quickLoad' and 'stuckLoad' substates can be assigned parameter 'loadType' with values of 0, 1 and 2.
Assuming that you can go from "Any State" to 'loadGun' state with trigger parameter 'load', and your SoldierAnimator reaches a point where it has to load gun, you can do something like this:
public class SoldierAnimator : MonoBehaviour
{
public Animator _animator;
void someUserInputEvent()
{
//... Some code here...
loadGun();
}
void loadGun()
{
int animType = Random.Range(0, 3);
_animator.SetInt("loadType", animType);
_animator.SetTrigger("load"); //Now your animations are randomized
// You can also experiment with _animator.speed = xx, for
// different speeds of loading animation, probably randomized a
// little, but then add an event to end of the animation and
// on the event, set speed back to 1.
}
}
What i would suggest you to do is set up conditions such that when the conditions is met, certain actions would be performed.
Transitions define not only how long the blend between states should take, but also under what conditions they should activate.
You can set up a transition to occur only when certain conditions are true.
To set up these conditions, specify values of parameters in the Animator Controller.
Also you can try : ordered interuptions , transistion offsets or transistion duration to achive your goals.
Further edits:
In this case, your higher-level script will need to set the character's animation parameters so that the avatar does what's specified in the text file. It might even be better to use Animator.Play() or .CrossFade() to directly change the animation state rather than setting an animation parameter.
For example, lets say your character 3 twitches at time 02:49. Then at 02:49 the script on character 3 (but only on character 3) should either set a trigger parameter such as "twitch" to true, or play an animation state directly such as Animator.Play("twitch").
So in effect all your soldiers would have different scripts each assigned to them.
Scripts have public properties that you set in the inspector. You can define a property for the character's number. This value would be unique for each character.
does this answer your question? sorry if i still didnt get your question

Changing Sprites using scripts in Unity2D C#

I am wanting to make a birds-eye view pixel-art game.
I currently have two sprite sheets set up, and split and whatnot
groundSheet and characterSheet these are split up into
ground_0_0_0 (A concrete floor)
ground_1_0_0 (grass)
character_0_0_0 (man idle animation frame 1)
character_0_0_1 (man idle animation frame 2)
character_0_1_0 (man run animation frame 1)
character_0_1_1 (man run animation frame 2)
character_1_0_0 (woman idle animation frame 1)
character_1_0_1 (woman idle animation frame 2)
character_1_1_0 (woman run animation frame 1)
character_1_1_1 (woman run animation frame 2)
The numbers after are a note as to:
first number - the main set of sprite animations (eg man)
second number - the animation set in use (eg run or idle)
third number - the frame of said animation.
(the ground has this as i plan to have animated grounds late on)
Now, I wish to make a script for the character (and ground alike) that has an editable value that is view able in the unity editor, for example how things like the sprite renderer has sprite, colour etc. Which dictates what first number to use (see above) what second number and the delay for the animation of the third number. This will then tell the sprite renderer what pictures to load and how quickly to load them. I also wish for the script to scan for the file starting with for example character_0_0_ and then count how many files after it, so it knows what to do when animating. I would like this script to be checking for a change in one of the variables viewable in the unity editor to change and as soon as it does it checks everything it needs for an animtion.
Something else could be done where there is only 1 box to edit in unity, which you put character_0_0_ or ground_1_0_ or something similar, and it checks everything that way (it also makes the script universal, and usable on the ground, character and walls (which I am adding later)).
This may seem confusing, but it make sense for me and many of you will probably mention a much easier way to do animations and such, but please only say these if it does what I want above.
For scripts and such my file layout:
/Assets
/scripts
ground.cs
character.cs
/sprites
characterSheet.png
character_0_0_0
character_0_0_1
character_0_1_0
character_0_1_1
character_1_0_0
character_1_0_1
character_1_1_0
character_1_1_1
groundSheet.png
ground_0_0_0
ground_1_0_0
(For some reason Stack overflow said the above was code, so i had to make it as that)
ground.cs and character.cs are the scripts in which I want to made as explained above.
In my object view thingy I have
Main Camera
ground
character
I am practically a newb to C# and JS I know bascially the grammar of C# (like where to use {} and put ; at the end of the lines). If you help me with this, i request that you explain the script, like use the // thing to simply explain what each command does, I know a few but not all of them. And I know someone is going to say it is really well documented in tutorial X and such, but most tutorials are not in unity 5 and while helping with the matter do not touch on it exactly.
Thank you for your help, if there is anything about this question/request that you do not understand (It is pretty complex) I will explain.
Maybe I am completely wrong, but it seems to me that you are trying to recreate an Animation system.
Is there a specific reason for which you wouldn't use Unity's animation system?
You can do everything that you describe here with it (change sprite, choose animation speed). And you would have almost no code to write. Just drag and drop you sprites in the editor for a start
EDIT - answer to first comment:
What you should do is create all the animations you need. Then in the animator, you choose which condition will trigger a transition to another animation (for instance, boolean jump is true will transition to animation jump). Then in your code you can call GetComponent().SetBool("Jump", true).
To have different character, you can create different gameObjects (one per character). They all have a different animator with animations specific to the character.
The other solutiojn if you really want one one gameObject and one animator is that you also add string condition to you animation (example, if character=="character1" and jump==true, transition to jump animation).
If I were you I would really focus on testing and learning all you can do with Unity animator. I can't think of a case were you would need to recreate the animation system yourself
Your question was long winded and hard to understand but ill try to help,
firstly if you want editable values in the unity editor I would Suggest using a serialized structure of information like this
[System.Serializable] // this makes it viewable in the inspector
public struct Sprite_Manager;
{
public Sprite[] Render_Sprites; // array of sprites to store sprites
public SpriteRenderer S_Renderer;
public float Anim_Delay;
}
public class Character : MonoBehavior {
Sprite_Manager SMG = new Sprite_Manager(); // instantiate a new instance of the struct
void Set_Sprite()
{
for(int i = 0; i < SMG.Render_Sprites.Length; i++)
{
SMG.S_Renderer.sprite = SMG.Render_Sprites[i];
}
}
void Update
{
Invoke("Set_Sprite", SMG.Anim_Delay);
}
}
Not sure if this is exactly what your looking for but this is one way you could setup a structure of sprite based information and use Invoke to setup some sort of delay when passing new sprites to the renderer.

When i pick an object from the ground, my script does something unexpected

I'm currently working on a script that can pick up an item, and drop it with the click of the left mouse button. I'm also planning on addint rotating of an item and some icons to display whenever i do one of those actions.
I'm currently very new to this, so i might be trowing myself out in the depths. But i would like to try.
Here's my code:
public class PickUp : MonoBehaviour {
public Transform onHand;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
if(Input.GetMouseButton(1)){
this.transform.position = onHand.position;
}
}
void OnMouseDown () {
GetComponent<Rigidbody>().useGravity = false;
this.transform.position = onHand.position;
this.transform.parent = GameObject.Find("Player").transform;
}
void OnMouseUp () {
this.transform.parent = null;
GetComponent<Rigidbody>().useGravity = true;
}
}
So far it kind of works.. I've some trouble picking up my object, it does not always let me. I have to click a couple of times, before it actually gets a hold on the object. When it does, the objects starts flying upwards for some weird reason i do not understand. I still have a hold on it, i can still walk around with it and as soon as i let go it falls down.
Based on the limited amount of data you have shown, I can suggest some common things to check / try. If you update with more details I'll try and help you further.
What value is assigned to your public Transform onHand variable?
Is there a reason why you are doing click detection in two places? Try deleting the lines inside the "Update" method.
The OnMouseDown method should be enough. However, for OnMouseDown to work, your object needs to have a physics collider setup. Check to see if you have a collider and that it's dimensions match what you would expect.
For debug purposes, try setting "isKinematic" to true on your pickup's rigidbody (from the inspector, permanently) this should disable gravity and other forces from moving your pickup object, so you can test out the rest of your code.
Also when you pick it up, set it's transform position to 0,0,0
This should make the object follow the player at the exact center spot of the player object.
Once you verify this works correctly, put features back in and see if any of them break the setup.
Start by setting the position back from 0,0,0 to onHand and then check if the pickup actually appears on the player's hand.
If not, check the value of the onHand variable.
Then you can turn off isKinematic and see if everything is still okay.
As a side note:
You might want to keep using isKinematic instead of disabling gravity. You could set it as kinematic when it's picked up to stop any forces from affecting the pickup's position, while the pickup itself will still have an effect on other rigidbodies.
Then when you drop it on mouse up, just turn off isKinematic again

Unity; animation on prefab

Tried to find this kind of problem around the net but failed so...
Here's the thing - I have a prefab gameobject that is to represent a unit, portrait more specifically. It has several scripts attached and an Animation component with two animations: Static and Selected.
The prefab is instantiated, moved freely and, after placing, it can be clicked to select it, which should, aside from executing a bit of code, start the Selected animation.
Using this code:
void OnMouseDown(){
//
//Some inside stuff
//
if (this.GetComponent<UnitHandling> ().thisUnit.Selected)
this.animation.Play("Selected");
if(this.animation.IsPlaying ("Selected"))
Debug.Log("Animation of selection is playing");
}
I checked that the animation seems to be playing (at least the Debug message is showing) but I see no animation... What am I doing wrong?
Try making an animation state using mechanim, and play it using this:
GetComponent<Animator>().CrossFade("Selected", 0);
https://docs.unity3d.com/Documentation/ScriptReference/Animator.CrossFade.html
https://docs.unity3d.com/Documentation/Manual/MecanimAnimationSystem.html

Categories

Resources