In cocos2dx, I use the class skeletonAnimation to create the skeleton animation which uses the resources exported by spine. We know the class skeletonAnimation is the subclass of node not is sprite.
How to do to make the skeleton animation flip the node as it like to use the method setFlippedX() in sprite node.
Use the method Which is inherited from class Node: setScaleX(-1), it works!
I had created methods to flip the skeleton animation.
void setFlipX(bool flipX) {
if(flippedX != flipX) {
flippedX = flipX;
flippedX ? setScaleX(-getScaleX()) : setScaleX(getScaleX());
}
}
void setFlipY(bool flipY) {
if(flippedY != flipY) {
flippedY = flipY;
flippedY ? setScaleY(-getScaleX()) : setScaleY(getScaleX());
}
}
and call the it as:
spinefile->setFlipX(true);
spinefile->setFlipY(true);
Related
I want to create a game in flutter with flame. For this game I want to detect swipes.
I could implement a tap recognition with the help of a tutorial. But I could not implement it with swipe detection.
my main with Taprecognition looks like this:
My main function is
void main() async{
Util flameUtil = Util();
await flameUtil.fullScreen();
await flameUtil.setOrientation(DeviceOrientation.portraitUp);
GameManager game = GameManager();
runApp(game.widget);
TapGestureRecognizer tapper = TapGestureRecognizer();
tapper.onTapDown = game.onTapDown;
flameUtil.addGestureRecognizer(tapper);
}
In my GameManager class I do have:
class GameMAnager extends Game{
// a few methods like update, render and constructor
void onTapDown(TapDownDetails d) {
if (bgRect.contains(d.globalPosition)) { //bgRect is the background rectangle, so the tap works on the whole screen
player.onTapDown();
}
}
And my player class contains:
void onTapDown(){
rotate();
}
Now I want to change this to rotate in the direction of the swipe instead of onTapDown.
I tried to somehow add
GestureDetector swiper = GestureDetector();
swiper.onPanUpdate = game.onPanUpdate;
to my main and
void onPanUpdate() {
}
to my gameManager class. But I cannot find anything similar to TapDownDetails for panning.
Any suggestions on this?
I saw some help for this to wrap the widget in a GestureDetector and use it like this:
GestureDetector(onPanUpdate: (details) {
if (details.delta.dx > 0) {
// swiping in right direction
}
});
But I couldn't make it work on my project.
You can use the HorizontalDragGestureDetector (or PanGestureRecognizer if you need both axes)
use the following in your main method
HorizontalDragGestureRecognizer tapper = HorizontalDragGestureRecognizer();
tapper.onUpdate = game.dragUpdate;
and then the following in your GameManager
void dragUpdate(DragUpdateDetails d) {
// using d.delta you can then track the movement and implement your rotation updade here
}
That should do the trick :D
If you need both axes, you can use PanGestureRecognizer (as #Marco Papula said).
Use this in your main method:
PanGestureRecognizer panGestureRecognizer = PanGestureRecognizer();
panGestureRecognizer.onEnd = game.onPanUpdate;
flameUtil.addGestureRecognizer(panGestureRecognizer);
and your onPanUpdate method:
void onPanUpdate(DragEndDeatils d) {
if(d.velocity.pixelsPerSecond.dx.abs()>d.velocity.pixelsPerSecond.dy.abs()) {
// X Axis
snake.velocity = d.velocity.pixelsPerSecond.dx<0 ? LeftSwipe : RightSwipe;
} else {
// Y Axis
snake.velocity = d.velocity.pixelsPerSecond.dy<0 ? UpSwipe : DownSwipe;
}
}
If you are using a newer (v1) version of Flame, you no longer need to wrap it in your own GestureDetector (thought you can). Now Flame has built in wrappers for all events, including panning! You can mix your game with:
class MyGame extends BaseGame with PanDetector {
// ...
}
And implement onPanUpdate to get the desired behaviour; or use a myriad of any other detectors (check the documentation for more options and details on how to use it).
I have been trying to implement the standard gestures leap motion provides such as the circle gesture and swipe gesture but none of them seems to work. I'm having a hard time understanding why most method that exists in the API are not being recognised in Unity.
Below is code I have used to get a circle gesture.
using UnityEngine;
using System.Collections;
using Leap;
public class LeapTest : Leap.Listener {
public Leap.Controller Controller;
// Use this for initialization
public void Start () {
Controller = new Leap.Controller(this);
Debug.Log("Leap start");
}
public override void OnConnect(Controller controller){
Debug.Log("Leap Connected");
controller.EnableGesture(Gesture.GestureType.TYPECIRCLE,true);
}
public override void OnFrame(Controller controller)
{
Frame frame = controller.Frame();
GestureList gestures = frame.Gestures();
for (int i = 0; i < gestures.Count; i++)
{
Gesture gesture = gestures[0];
switch(gesture.Type){
case Gesture.GestureType.TYPECIRCLE:
Debug.Log("Circle");
break;
default:
Debug.Log("Bad gesture type");
break;
}
}
However, when I put this code into unity3D it doesn't recognise the following lines of code from the code above:
Leap.Controller
.EnableGesture(Gesture.GestureType.TYPECIRCLE, true);
GestureList gestures = frame.Gestures();
I don't understand what I am missing out here, or is it depreciated? Please, can someone explain? Thankyou
Gestures were deprecated in Orion (v3 and above), so if you're using one of the Orion versions of Leap Core Assets then you'll get this error. You can still use the v2 assets if you want to use these Gestures, otherwise you'll need to implement them yourself.
I have made a scriptable object which has a one property a public sprite. I want to have one version of sprite added everywhere I want.
With the possibility that if I ever want to change it I will just pin another sprite to scriptable object and in every place where it is pinned the sprite will change.
Is there any way to walk thought this problem or any other idea to make one object where I will store one Sprite and pin it to multiple objects.
Finally is this concept possible in Unity?
I have already thought about:
Deriving prom Sprite Renderer but the class is sealed, so i cannot make my own version of it this way
Creating my own custom version of Sprite Render cause if an any update come I would have to make yet again another version.
I think you can use prefabs to achieve the same thing as you need:
You can create prefab by dragging and object to your assets.(Your prefab will be just an object with transform and e.g. Sprite Renderer)
After creating prefab you can copy it as many times as you want.
Than when you decide to change the sprite just simply go to your prefab and edit sprite there. Now every instance of your prefab will have sprite changed.
It is possible with C# events. First, make your ScriptableObject call event whenever sprite is set. Allow Sprite to be set only using property (or method), so that you could track the change, like this:
public sealed class SpriteObject : ScriptableObject
{
public event Action SpriteChanged;
[SerializeField]
private Sprite _sprite;
public Sprite Sprite
{
get { return _sprite; }
set
{
if(_sprite == value)
return;
_sprite = value;
SpriteChanged?.Invoke();
}
}
}
Then, you need script, that will react to changed and assign the changed sprite to SpriteRenderer. So, something like this:
NOTE: name is purely for example. Do NOT name your classes like this!
[RequireComponent(typeof(SpriteRenderer))]
public class ScriptThatUsedSpriteObject : MonoBehaviour
{
public SpriteObject spriteObject;
private SpriteRenderer spriteRenderer;
/// Called once the script is created.
private void Awake()
{
spriteRenderer = GetComponent<SpriteRenderer>();
if(spriteObject != null)
{
spriteRenderer.sprite = spriteObject.Sprite;
spriteObject.SpriteChanged += HandleSpriteChanged;
}
}
/// Called whenever sprite is changed inside SpriteObject.
private void HandleSpriteChanged()
{
spriteRenderer.sprite = spriteObject.Sprite;
}
}
Now, if some script changes sprite in SpriteObject, every ScriptThatUsedSpriteObject will automatically update their sprites.
public class PublicSprite : MonoBehaviour {
public Sprite publicSprite;
#region Singelton
public static PublicSprite instance;
private void Awake()
{
if (instance != null)
{
Debug.LogWarning("More than one instance found");
return;
}
instance = this;
}
}
get the sprite like this:
PublicSprite.instance.publicSprite;
as Mentioned here, you probably want to use a Singelton. It is best to avoid the use of them only if its necessary as its a very bad programming practice. (you can learn more on why to avoid them here: What is so bad about singletons?
However, I can't think of another way of doing what you seek for.
In my game, I have two scene.
What I want to achieve is if user navigates from one scene to another, background audio specific to each should be played from start(audio length=0)
But all my efforts are in vain.
I tried using 'Pause' Method of audioSound
I tried
create a new game object and assign this scene background score to it and play
destroy gameObject created for another scene if there was any
But it doesn't give the result that I want.
I searched for finding how to play audioClip from start and stop other audioClip playing but didn't find any.
I know I'm not supposed to ask for code on stack overflow but if anyone has achieved this or has some pseudo code request you to provide it
I'm not sure I understand your question properly, since it seems the simplest scenario for background music.
If you really want a change of audioclip in every scene, let's say Scene A must play Clip A and Scene B must play Clip B, and both clips should be played as soon as a scene is loaded, you just need to create a game object in both scenes with an Audio Source component, with the Play On Awake flag active, and then just assign the appropriate clip for the scene (i.e.: assign Clip A in the Audio Clip field of the Audio Source component of Scene A game object, and do the same with Clip B for Scene B).
That's pretty much it.
If you looking at the detail code then you can try this code.
First : Make a script "SoundFxScript.cs" // You can modified as you want
Insert this code :
public class SoundFxScript : MonoBehaviour {
//Background Music
public AudioSource Scene1_Sound;
public AudioSource Scene2_Sound;
// Use this for initialization
void Start () {
PlayBackgroundMusic ();
}
// Update is called once per frame
void Update () {
}
public void PlayBackgroundMusic() {
if (UnityEngine.SceneManagement.SceneManager.GetActiveScene ().name == "Scene1") {
Scene1_SoundPlay();
} else if (UnityEngine.SceneManagement.SceneManager.GetActiveScene ().name == "Scene2") {
Scene2_SoundPlay();
}
}
public void Scene1_SoundPlay() {
Scene1_Sound.Play ();
Scene2_Sound.Stop ();
}
public void Scene2_SoundPlay() {
Scene1_Sound.Stop ();
Scene2_Sound.Play ();
}
// Step Fifth
public void LoadTheScene (string Scenename) {
UnityEngine.SceneManagement.SceneManager.LoadScene (Scenename);
sf.PlayBackgroundMusic ();
}
}
Second : Make Gameobject name = "SoundMusic" at the first scene and add component script SoundFxScript.cs. In gameobject "SoundMusic" you can add you background music for scene1 and scene2.
Third : Make a singleton file Singleton.cs
Insert this code :
public class Singleton : MonoBehaviour {
static Singleton instance = null;
void Start ()
{
if (instance != null)
{
Destroy(gameObject);
return;
}
DontDestroyOnLoad(gameObject);
instance = this;
}
}
Fourth : at gameobject "SoundMusic" add component script "Singleton.cs"
Fifth : How To Call In Another Scene (Load Scene). This method is inside SoundFxScript.cs
Example You have a method to call a load scene. Try this method :
Call it with : LoadTheScene("Scene2") // Call scene2
In here you can call your SoundFxscript.cs Component from any script you have.
Example :
SoundFxScript sf;
sf = GameObject.Find ("SoundMusic").GetComponent<SoundFxScript> ();
And you can use method LoadTheScene to load a new scene and the background music will RePlay again according to the what Scene is it.
That's All.
I have a working collision system to sprites that i dont want "player" to pass. Problem is that i have no idea what should i execute on collision to make player not pass sprites.
wallCollision() method is currently empty.
if(tmxTileProperties.containsTMXProperty("collision", "1")) {
Rectangle rect = new Rectangle(tmxTile.getTileX(), tmxTile.getTileY() ,128, 128, mEngine.getVertexBufferObjectManager())
{
#Override
protected void onManagedUpdate(float pSecondsElapsed)
{
if (player.collidesWith(this))
{
wallCollision();
}
}
};
rect.setVisible(false);
mainScene.attachChild(rect);
}
The question located here addresses this. The method below creates a JBox2D body at the same position as the blocked tile. I'm not sure how this works in conjunction with the pathfinding to exclude blocked tiles, but I've seen the same approach used in other places, assuming you're using GLES2. Hope this helps.
private void createUnwalkableObjects(TMXTiledMap map){
// Loop through the object groups
for(final TMXObjectGroup group: this.mTMXTiledMap.getTMXObjectGroups()) {
if(group.getTMXObjectGroupProperties().containsTMXProperty("wall", "true")){
// This is our "wall" layer. Create the boxes from it
for(final TMXObject object : group.getTMXObjects()) {
final Rectangle rect = new Rectangle(object.getX(), object.getY(),object.getWidth(), object.getHeight());
final FixtureDef boxFixtureDef = PhysicsFactory.createFixtureDef(0, 0, 1f);
PhysicsFactory.createBoxBody(this.mPhysicsWorld, rect, BodyType.StaticBody, boxFixtureDef);
rect.setVisible(false);
mScene.attachChild(rect);
}
}
}
}