Is there a way to raise a flag on the Navmesh navigation end, or to use a callback when it finish?
I want to run a function when my objection reach to the desire position, I can check on every frame update if the navigation has finished but I want a more elegant and efficient solution.
Thanks.
It depends what you mean by "ends", if you want to know when a path is no longer available for the NavAgent, you can use pathStatus, for example you could write:
if(myNavAgent.pathStatus != NavMeshPathStatus.PathComplete) {
// Do stuff
}
If you me reaching a location such as a "waypoint" you can use myNavAgent.remainingDistance then check if it is less than a certain value.
Here's the unity NavAgent scriptingAPI doc link: https://docs.unity3d.com/ScriptReference/AI.NavMeshAgent.html
If this doesn't work, let me know!
I have Thought the same question and i couldn't find a callback, However i managed to solve with triggers. For example if my agent goes point a, i put trigger that position and when my agent touches it i stopped agent.
Related
I am not sure where to start so asking for some help. I want to create a script that detect if a certain mesh is hit by players right hand. Every time the mesh is hit I want to increase points for player by 1.
Anyone who can nudge me in the right direction here?
Thanks!
EDIT:
I have added this script in StarterCharacterScripts:
game.Players.LocalPlayer.Character:WaitForChild("RightHand").Touched:Connect(function(hit)
local part1 = workspace.CoinsClouds["Meshes/SackOfGoldNoCoins1"]
part1.Touched:Connect(function(hit)
if hit.Name == "RightHand" then
print(hit.Name)
end
end)
end)
This will register when I bump into the part with the right hand, BUT it will register it 5-20 times in a split second every time I bump into the part with the right hand. See attached image. Anyone know why? I would like it to register only once when the right hand is bumped against the part, or even better, only when the user punch the part/mesh. I have tried to add a wait after RightHand is found, but that doesn't work.
PS! I don't know if this is the right way to script it...
Below is an example of the code you would use. It will check if your part is touched by either the right or left hand and it will run whatever is inside of your if statement, in this case it will increase whatever your score is by 1.
local part = workspace.Part -- reference the part here
local debounce = false --used to check for debounce
part.Touched:Connect(function(hit)
if hit.Name == "RightHand" or "LeftHand" then -- checks if a hand touched it
if not debounce then --Check that debounce variable is not true
debounce = true --currently touching the part
print("hit")
wait(1)
debounce = false
end
end
end)
In relation to your new question it is to do with debounce. Roblox has an entire article on it here: https://developer.roblox.com/en-us/articles/Debounce
Basically you would have to add a new if statement to check that the player isn't already touching this part if it is it wont repeat the what is inside the if statement. The code sample above has been edited to work with debounce.
I have monster named Fungant in my 2D platform game.
It can hide as mushroom and rise to his normal form.
I try to handle it in code, but I don't know how to get information about finished animation (without it, animation of rising and hiding always was skipped).
I think the point there is to get info about complete of the one of two animations - Rise and Hide.
There is current code:
if (
fungantAnimator.GetCurrentAnimatorStateInfo(0).IsName("Fungant Rise")
)
{
fungantAnimator.SetBool("isRising", false);
isRisen = true;
fungantRigidbody.velocity = new Vector2(
walkSpeed * Mathf.Sign(
player.transform.position.x - transform.position.x),
fungantRigidbody.velocity.y
);
}
if (fungantAnimator.GetCurrentAnimatorStateInfo(0).IsName("Fungant Hide"))
{
fungantAnimator.SetBool("isHiding", false);
isRisen = false;
}
I try this two ways:
StateMachineBehaviour
I would like to get StateMachineBehaviour, but how to get it?
No idea how to process this further.
AnimationEvents
Tried to do with animation event but every tutorial have list of functions to choose (looks easy), but in my Unity I can write Function, Float, Int, String or select object (what I should do?).
I decided to write test() function with Debug only inside, and create AnimationEvents with written "test()" in function field, but nothing happens.
Same as above, no more ideas how to process this further.
I personally would use animation events for this. Just add an event to the animation and then the event plays a function after the animation transition is finished.
For more information on how to use animation events you can click here.
This post may also help you to add an event when the animation is finished.
I hope this answer helps you to solve this problem.
Im trying to make it so after a player touches a certain brick it falls,that part works.But what I want it to do is to respawn after a set amount of time and the old one be destroyed.Im trying to make an obby with falling bricks.I have no clue what to do
That's pretty easy, all you need to do is add a wait() and then once it's waited said amount of time make it change the position of the block back to what it was. Here:
function onTouched(humanoid)
wait(3)
script.Parent.Position = Vector3.new(0.57, 1.2, 1.23)
end
script.Parent.Touched:connect(onTouched)
Put this script in the brick you want 'regenerated' and change the wait and position to what you want.
I have an idle player animation and I want to do a smooth transition between some animations. The idle animation is the default one and from that transition I want to be able to switch to another state(let's say fight) and then back to idle. The code for the idle character animation is currently like :
self.addChild(playerAnimation)
playerAnimation.runAction(SKAction.repeatActionForever(
SKAction.animateWithTextures(playerAnimationManager.idleManAnimation.textureArray, timePerFrame: 0.1)))
Now, this is scheduled to go on forever for now, but I would need to intercept it and add a new animation on top of that (which is the same character, in a new state). I was thinking that I should stop the idle animation, switch to the new one and then back to idle when finished but I am not convinced that this is the best way of chaining animations and I haven't really found a good resource explaining how to go about it.
Any suggestions ? Thanks !
Depending on how short your texture array is, you might be able to do this.
I will try to explain without code seeing how I use objective C and you use Swift
First make a property or variable that can be called by any subroutine in this class file. It should be Boolean and should be set to NO. You could call it idleFlag.
Next make a method that changes the animation to fight mode. This change would be by removing the idle animation and replacing it with the fight animation. This method also set's idleFlag to NO. Let's call the method "beginFightAnim"
And last, in your repeatActionForEver idle animation, right after your animateWithTextures animation, add a runBlock animation. In this block define a static variable (one that will be remembered in the calling of the block over and over) and increment it by +1, add an "if statement" that looks something like this -> if (my_static_var == number_of_frames_in_texture_animations && idleFlag). And in the "if statement" set the static variable to 0 and call "beginFightAnim"
After this all you have to do to change the animation is set idleFlag to YES.
Hope it works!
If you have any problems, please comment below.
I want to do a series of examples to make it easier to understand the matter. Suppose you have your node called playerAnimation, a typical atlasc with a plist where you have
player-idle1.png
player-idle2.png
player-idle3.png
...
If you want to intercept in real-time your animation to know what frame is running in that moment you can do:
override func update(currentTime: CFTimeInterval) {
if String(playerAnimation.texture).rangeOfString("player-idle") != nil {
print(String(playerAnimation.texture))
}
}
At this point, after you have assigned a "key" to your action (withKey:"idleAnimation") you could stop your specific idle action when you preefer to start the other next animation.
Another good thing is to build a structure to know everytime your player status and modify this variable each time you launch a new action or animation:
enum PlayerStatus: Int {
case Idle = 1
case Fight = 2
case Run = 3
case Jump = 4
case Die = 5
...
}
var currentStatus: PlayerStatus!
Working in Objective-c at the moment.
I am drawing a path for my sprite to follow and it all seems to be working fine but i just had one question that didnt seem to be answered anywhere.
My first two points in the Bezier are rather close together in relation to the third point and when my sprite animates along this path it seems like it is being eased in to the animation with an abrupt stop at the end.
Is there a way to control this i'd like to have the animation be one consistent speed or possibly be eased out?
id bezierForward = [CCBezierTo actionWithDuration:totalDistance/300.f bezier:bezier];
[turkey runAction:bezierForward];
Give this a try:
id bezierForward = [CCBezierTo actionWithDuration:totalDistance/300.f bezier:bezier];
id easeBezierForward = [CCEaseOut actionWithAction:bezierForward rate:2.0]
[turkey runAction:easeBezierForward];
You will want to play with the rate value to see what ends up looking best to you. You may have to try out some of the other CCEaseOut options like CCEaseSineOut
Link: Cocos2d Ease Actions Guide
Should probably be something like this, according to the docs:
id bezierForward = [CCEaseOut actionWithDuration:totalDistance/300.f bezier:bezier];
[turkey runAction:bezierForward];
As stated in the docs:
Variations
CCEaseIn: acceleration at the beginning
CCEaseOut: acceleration at the end
CCEaseInOut: acceleration at the beginning / end