Play animations from Cocos Studio in sequence in cocos2d-js - cocos2d-x-3.0

I have created animations ( attack, dropWeapon, run, retreat ) in Cocos Studio for Cocos2d-js and I can play that in code via
sprite = ccs.load( "res/solder.json" );
this.addChild( sprite.node );
sprite.node.runAction( sprite.action );
sprite.action.play( "attack", false ); // false means do not repeat / loop
How can I play animations one after another in Sequence ?
I have code when I create animation in code but not in Cocos Studio.

you can write a function with the list of animations as parameters and check
isComplete() for previous animation to start the next one

You can create a sequence of actions using cc.Sequence
var actionArray = [action1, action2, action3];
var seq = new cc.Sequence(actionArray);
sprite.runAction(seq);
Add all the actions to an array, and create a new action, where all of these actions would run in a sequence

Related

Flutter Flame Game Unit Test Not Working: How do I fix my test case below so that I can test tap events for flame components within my flame game?

Here is the development test I am trying to run:
testWithGame<ExampleGame>("back button can be tapped", ExampleGame.new,
(game) async {
await game.ready();
final Button component = game.backButton!;
int backButtonPointerID = game.children.length - 3;
game.onTapDown(
backButtonPointerID,
createTapDownEvent(game,
globalPosition:
Offset(component.position.x, component.position.y)));
expect(component.tapped, true);
});
Any thoughts as to why this isn't registering a tap? It should evaluate to true but evaluates to false. When playing the game itself it registers as true, but the unit test doesn't...
The button is most likely not added to the game yet, but will be added in the next tick (if you add it properly, it would help to have that code in the question too).
Try to run game.update after game.ready, or add await to the add call if you are doing it in the game's onLoad method.

How to trigger an entity's animation declared in .reality file?

In Reality Composer I created MyScene.rcproject, in MyScene I created a panel and its spin animation, the action sequence begins when its notification is posted from code.
When it's come to trigger the animation from MyScene.rcproject it works like I expect:
self.sceneAnchor = try MyScene.loadMyScene()
sceneAnchor.generateCollisionShapes(recursive: true)
sceneAnchor.notifications.spin.post()
But when I export MyScene.rcproject file to MyScene.reality and I implement it into another app project:
panelEntity = try? ModelEntity.load(named: "MyScene")
sceneAnchor.addChild(panelEntity)
I can't find any method to trigger the spin animation. Is it possible to trigger entity's animation, inside MyScene.reality file?
In RealityKit 2.0, if using .reality file instead of .rcproject, Notifications class is inaccessible.
public private(set) lazy var notifications = A.Scene.Notifications(root: self))

Unity3D How can I select multiple objects in 3D with a drag and select / lasso select?

I am struggling to find a good tutorial or informations that would allow me to select multiple objects in 3D in a user friendly manner.
So far, the best tutorial I found is this one : https://sharpcoderblog.com/blog/unity-3d-rts-style-unit-selection. The tutorial works by using the transform.position of the selectable objects and checking if it within the user's selection.
What I wish is to have the user be able to select a unit even if it is only partially within the user's selection such as most RTS games do ( both in 2D and 3D ).
One possibility would be to create a temporary mesh using the camera's clipping distances and the user's selection and then check for collisions but I was not able to find any tutorials using this method nor do I know if it is the best approach to the subject.
If I understand correctly you want to
somehow start a selection
collect every object that was "hit" during the collection
somehow end the collection
Couldn't you simply use raycasting? I will assume simple mouse input for now but you could basically port this to whatever input you have.
// Just a little helper class for an event in the Inspector you can add listeners to
[SerializeField]
public class SelectionEvent : UnityEvent<HashSet<GameObject>> { }
public class SelectionController : MonoBehaviour
{
// Adjust via the Inspector and select layers that shall be selectable
[SerializeField] private LayerMask includeLayers;
// Add your custom callbacks here either via code or the Inspector
public SelectionEvent OnSelectionChanged;
// Collects the current selection
private HashSet<GameObject> selection = new HashSet<GameObject>();
// Stores the current Coroutine controlling he selection process
private Coroutine selectionRoutine;
// If possible already reference via the Inspector
[SerializeField] private Camera _mainCamera;
// Otherwise get it once on runtime
private void Awake ()
{
if(!_mainCamera) _mainCamera = Camera.main;
}
// Depending on how exactly you want to start and stop the selection
private void Update()
{
if(Input.GetMouseButtonDown(0))
{
StartSelection();
}
if(Input.GetMouseButtonUp(0))
{
EndSelection();
}
}
public void StartSelection()
{
// if there is already a selection running you don't wanr to start another one
if(selectionRoutine != null) return;
selectionRoutine = StartCoroutine (SelectionRoutine ());
}
public void EndSelection()
{
// If there is no selection running then you can't end one
if(selectionRoutine == null) return;
StopCoroutine (selectionRoutine);
selectionRoutine = null;
// Inform all listeners about the new selection
OnSelectionChanged.Invoke(new HashSet<GameObject>(selection);
}
private IEnumerator SelectionRoutine()
{
// Start with an empty selection
selection.Clear();
// This is ok in a Coroutine as long as you yield somewhere within it
while(true)
{
// Get the ray shooting forward from the camera at the mouse position
// for other inputs simply replace this according to your needs
var ray = _mainCamera.ScreenPointToRay(Input.mousePosition);
// Check if you hit any object
if(Physics.Raycast(ray, out var hit, layerMask = includeLayers ))
{
// If so Add it once to your selection
if(!selection.Contains(hit.gameObject)) selection.Add(hit.gameObject);
}
// IMPORTANT: Tells Unity to "pause" here, render this frame
// and continue from here in the next frame
// (without this your app would freeze in an endless loop!)
yield return null;
}
}
}
Ofcourse you could do it directly in Update in this example but I wanted to provide it in a way where you can easily exchange the input method according to your needs ;)
From UX side you additionally might want to call a second event like OnSelectionPreviewUpdate or something like this every time you add a new object to the selection in order to be able to e.g. visualize the selection outcome.
I might have understood this wrong and it sounds like you rather wanted to get everything inside of a drawn shape.
This is slightly more complex but here would be my idea for that:
Have a dummy selection Rigidbody object that by default is disabled and does nothing
don't even have a renderer on it but a mesh filter and mesh collider
while you "draw" create a mesh based on the input
then use Rigidbody.SweepTestAll in order to check if you hit anything with it
Typed on smartphone but I hope the idea gets clear
I think I would try to create a PolygonCollider2D because it is quite simple comparing to creating a mesh. You can set its path (outline) by giving it 2D points like location of your pointer/mouse. Use the SetPath method for it. You can then use one of its methods to check if another point in space overlaps with that collider shape.
While the PolygonCollider2D interacts with 2D components you can still use its Collider2D.OverlapPoint method to check positions/bounds of your 3D objects after translating it to 2D space.
You can also use its CreateMesh method to create a mesh for drawing your selection area on the screen.
You can read more about the PolygonCollider2D here.
Hope it makes sens and hope it helps.

How I can instantiate various prefabs in a given time for each?

I am developing a video game Guitar Hero type. I just finished everything. What I need is to configure the notes.
I have a script that instantiates me a prefab (a note) and generates time to time. But there is not only one note. There are 23 and I wonder if it is possible to instantiate each with different timers and within the same script.
For example, the first note should be generated to 1 second and second to 3 seconds.
This is the script that I have:
#pragma strict
var yellowNote: GameObject;
var time = 1;
function Start () {
while (true) {
yield WaitForSeconds (time);
Instantiate (yellowNote, transform.position, Quaternion.identity);
}
}
You could define an array of times you'd like between each instantiation. Then, iterate through the array with a for loop and do the WaitForSeconds inside this loop.

make a simple transition in easelsjs

I'm using easelsjs and I need to make a simple transition.
Just change the opacity of the stage gradually.
I'm using the alpha property and the Ticker but I don't see the transition but only the last stage of it.
Is there a simple example for this - I tried to look but couldn't find
I don't know if you want to change the stage opacity or the shape opacity, but if you want your entire canvas to have less opacity, you can simply use JavaScript + CSS transitions to do it. No need for EaselJS in this case.
But if you want to create alpha transitions on canvas objects you should take a look at TweenJS, it simplifies the animation process a lot.
Also, if you want to continue using EaselJS only (or with TweenJS), you'll need to implement the ticker properly, here's how I create my ticker function:
createjs.Ticker.on("tick", tick);
createjs.Ticker.setFPS(60); // This will call the tick() function at every 1000/60ms
function tick() {
stage.update();
}
And then you'll need to say when your button was clicked to your ticker function, so it can decrease your object's alpha every frame. I highly recommend using TweenJS instead of doing this (I've put a TweenJS demonstration at the end of this answer):
$(document).ready(function () {
var stage = new createjs.Stage(canvas);
var s = new createjs.Shape();
s.graphics.beginStroke("#F00").beginFill("#FF0000").drawRect(150.5, 100.5, 300, 300);
stage.addChild(s);
$("#d").click(function () {
s.fadeOut = true;
});
// Tick:
createjs.Ticker.on("tick", tick);
createjs.Ticker.setFPS(60);
function tick() {
if(s.fadeOut){
s.alpha -= 0.01;
s.fadeOut = (s.alpha > 0.4);
}
stage.update();
}
});
I've simplified your code a little bit too. Here's how the code inside the click event handler would look using TweenJS:
createjs.Tween.get(s).to({alpha: 0.4},1000);
Note that both EaselJS and TweenJS work together.