Unity 3D - Multiple targets not working - image

I'm making an application in Unity 3D for Android which consists in detect a pattern with the phone camera and then it appears a plane (that acts like a button) that starts a video if you click it.
So, I've 4 different Image Targets with 4 different patterns and inside every Image Target it is a plane that appears when the pattern is detected. When you touch the plane it executes the following script:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class PlayVideo1 : MonoBehaviour
{
public string moviePath = "video1.mp4";
void Update () {
// Code for OnMouseDown in the iPhone. Unquote to test.
for (int i = 0; i < Input.touchCount; ++i) {
if (Input.GetTouch(i).phase.Equals(TouchPhase.Began)) {
Debug.Log("Starting Movie: " + moviePath);
Handheld.PlayFullScreenMovie (moviePath, Color.black, FullScreenMovieControlMode.Full);
Debug.Log("All Done!");
}
}
}
}
Every plane has a different script with a different moviePath, for example:
The plane 1 has the PlayVideo1.cs with the moviePath "video1.mp4".
The plane 2 has the PlayVideo2.cs with the moviePath "video2.mp4".
The plane 3 has the PlayVideo3.cs with the moviePath "video3.mp4".
The plane 4 has the PlayVideo4.cs with the moviePath "video4.mp4".
Then when I detect one of the 4 patters with the camera and the button appears when I click it always plays the same video ("video3.mp4" for example) even if the pattern I'm focusing with the camera is the one with the plane 1 or 2.
What am I doing wrong?
Thank you!

This is because your code does not check which plane is being clicked. What it is currently doing is just detecting whether there is any touch input.
Change your code to the below
//On MouseUpAsButton is a Monobehaviour event that is called on every collider
//where the interaction is like a button (i.e. click down and release on the same collider)
public void OnMouseUpAsButton () {
Handheld.PlayFullScreenMovie (moviePath, Color.black, FullScreenMovieControlMode.Full);
}
Also note that if you're using Unity 4.6 and above, you MUST have the Event System component attached to SOME GameObject in your scene, otherwise OnMouseUpAsButton will not get called.
Finally, there are a lot of other useful events that Monobehvaiour has, including OnMouseEnter, OnMouseDown, OnMouseExit, OnMouseUp etc. Link to Monobehaviour in Unity's Docs
P.S. Mouse events do work on mobile, so you can safely use it.

Related

Different animation in 2 directions

I’m really just a beginner & I have no idea how to use the animation in Unity properly. I’m working on a 2D platformer game. I managed to make the animation work, but the point is that my character should looks different from each side (so I can’t just flip the sprite). What’s the simplest way to for example, when pressing right he will use animation 1 and when pressing left he will use animation 2? Thanks in advance & sorry about my stupidity;)
Did you try using Animator Controller.
[RequireComponent(typeof(Animator))]
public class PlayerAnimation: MonoBehaviour
{
[SerializeField]private Animator _animator;
private const string DirectionParam = "Direction";
private void Update()
{
//On Right button clicked
if (Input.GetKeyDown(KeyCode.RightArrow))
{
//Play Right animation
_animator.SetInteger(DirectionParam, 1);
}else if (Input.GetKeyDown(KeyCode.RightArrow))
{
_animator.SetInteger(DirectionParam, -1);
}
else
{
_animator.SetInteger(DirectionParam, 0);
}
}
}
Drag this script on you player. This will also Add unity Animator Component on your game object.
Create Animator Object and place it on the animator component.
open Animator Editor from Window>Animation>Animator
Then create an int parameter in Animation Controller Window and name it "Direction".
Create two animation clips one for left move animation and another for right move animation
Drag these clips to the animator Window. Right click and create two transition and add condition with Direction parameter. You should create 3 animation clips and set that to idle and transition to idle when the direction value is 0.
Enjoy!

Unity 3D: Changing sprite animation using UI button

I'm following this tutorial on youtube about changing sprite animation in code, and I was wondering if I could change this to changing sprite animation using UI button. does anyone knows how to do this. Thank you!
EDIT:
The script that I reposed kind of works thanks to your help, it changes the sprite image from image one to image two but what I'm basically trying to achieve is that each time that I click the UI button the sprite image will change from sprite image one (UI button click)> sprite image two (UI button click)> sprite image three (UI button click)> then repeat the process instead of the sprite image automatically changing itself.
Buttons have an OnClick event http://docs.unity3d.com/ScriptReference/UI.Button-onClick.html
You just create a method that gets called when the button is clicked, in your case the changing sprite code. Seen as you are using a timer though you will need to use something like a bool because onClick() only gets called once when clicked, not every frame.
Look https://www.youtube.com/watch?v=J5ZNuM6K27E
bool b_RunSpriteAnim;
public void onClick(){
b_RunSpriteAnim = true;
}
void Update(){
if (b_RunSpriteAnim)
//your anim sprite stuff
}
Then once the sprite anim has finished, just toggle b_RunSpriteAnim to false and reset the timer.
Edited:
You don't need a boolean. I only thought you wanted it because you were using a timer (as based on the Youtube link). If you just want to change the sprite immediately then you do not need it. As for Imagethree not working, it's because you have never included it in your code. It isn't clear what you are trying to achieve with Imagethree, if you included this in onClick as well it would just overwrite the image two that was just set, so I am not sure what you are looking to achieve.
public void onClick(){
this.gameObject.GetComponent<SpriteRenderer>().sprite = Imagetwo;
}
Second Edit:
public Sprite[] Images;
//Index starts at one because we are setting the first sprite in Start() method
private int _Index = 1;
void Start(){
//Set the image to the first one
this.gameObject.GetComponent<SpriteRenderer>().sprite = Images[0];
}
public void onClick(){
//Reset back to 0 so it can loop again if the last sprite has been shown
if (_Index >= Images.Length)
_Index = 0;
//Set the image to array at element index, then increment
this.gameObject.GetComponent<SpriteRenderer>().sprite = Images[_Index++];
}

Libgdx FreeTypeFont: font generated dynamically doesn't scale in Label

I'm trying to figure out how to realize the HUD interface for my brand new game.
I wanted to create it by using the scene2d.ui set of widgets because I've heard that it's more suitable for a responsive UI.
So, I'm trying to create a simple HUD in which there's a score Label aligned at the top-right side of the screen and a pause Button placed on the top-left side of the screen.
Now... I'm using a root Table (as explained in the Table guide https://github.com/libgdx/libgdx/wiki/Table#quickstart) that fills the stage.
I wanted to create a custom class for handling all the hud interface such as:
public class Hud extends Table{
private Label scoreLabel;
private Button pauseButton;
public Hud(){
setFillParent(true);
BitmapFont font = (BitmapFont) MyGame.assetManager.get(Constants.COUNTERS_FONT_NAME);
LabelStyle labelStyle = new LabelStyle(font,Color.WHITE);
scoreLabel = new Label("score:0", labelStyle);
add(scoreLabel).width(2).height(1);
}
}
The issue I'm fighting with is the following: the text inside the Label does not stay inside the Label.
I mean: activating the debug mode I can see the rectangle representing the Label with the correct dimensions...but the text is completely out of bounds and does not scale.
As you can see the font I use is a BitmapFont that is generated when the Game starts via the library FreeTypeFont...The font is then added to the AssetsManager of the game.
I post the code I use for adding the font generator to the assets manager:
//Register the FreeTypeFontGeneratorLoader
InternalFileHandleResolver resolver = new InternalFileHandleResolver();
assetManager.setLoader(FreeTypeFontGenerator.class, new FreeTypeFontGeneratorLoader(resolver));
assetManager.setLoader(BitmapFont.class, ".ttf", new FreetypeFontLoader(resolver));
//Load fonts
FreeTypeFontLoaderParameter countersFontParameters = new FreeTypeFontLoaderParameter();
countersFontParameters.fontFileName = Constants.BASE_FONT_NAME;
countersFontParameters.fontParameters.size = 45;
countersFontParameters.fontParameters.borderColor = Color.BLACK;
countersFontParameters.fontParameters.borderWidth = 1;
assetManager.load(Constants.COUNTERS_FONT_NAME, BitmapFont.class, countersFontParameters);
As you can see I load just one BitmapFont with a size of 45 pixels.
I don't know what the problem is; I would like to try with a classic BitmapFont .fnt in order to see if the problem is in the way the BitmapFont is generated but I'd also like to keep the FreeTypeFont solution.
Thanks in advance,
Luca
P.S.
One thing about the Stage... it uses a ScalingViewport so the dimensions are not in pixels but in virtual units (because my Game uses Box2d and I need a common unit both for the rendering and the physic simulation).
I'm pretty sure that Label will not respond on automatic scaling of the viewport until you will call label.setFontScale( theScale ) explicite.
The best idea here, in my opinion, will be to create another stage exclusively for a HUD so you will have your stage with ScalingViewport (I admit I've never used this one - isn't it better to use some Fill or aomething like this one?) and another stage with FitViewport above for example.
I find it very reasonable and intuitive since it will be like having your HUD displayed on yours car windscreen when driving the car.
The code should looks like:
//in your show method
viewport = createYourScalingViewport();
stage = new Stage();
stage.setViewport(viewport);
HUDviewport = new FitViewport(screenWidth, screenHeight);
HUDstage = new Stage();
HUDstage.setViewport(HUDviewport);
...
//adding some actor to stages
stage.addActor(actor1);
stage.addActor(actor2);
//BUT
HUDstage.addActor( yourHudInstance );
...
//then in your render method act() and draw() stage then HUDstage so the HUD will be above stage
stage.act();
stage.draw();
HUDstage.act();
HUDstage.draw();
Remember of updateing HUDviewport in case of window resizing in the resize Screen method
I guess I've solved my problem.
It seems to be that it doesn't make sense to set the label dimensions.
If anyone needs to have a container that was tight to the text is rendered inside the label the best solution is to create a custom class like this below that extends an HorizonaltGroup (o VerticalGroup).
Let's imagine I need a score label for my game:
public class ScoreLabel extends HorizontalGroup{
...
}
Inside this class I create a Label property and I add it as an Actor.
public class ScoreLabel extends HorizontalGroup{
private Label scores;
public static final float FONT_SCALE = 0.9f;
public ScoreLabel(){
BitmapFont font = MyGame.assetManager.get(Constants.COUNTERS_FONT_NAME);
LabelStyle labelStyle = new LabelStyle(font, Color.WHITE);
scores = new Label(getScoreText(), labelStyle);
scores.setAlignment(Align.left);
scores.setFontScale(FONT_SCALE);
addActor(scores);
}
}
If you activate the debug mode you'll notice that there's a container that is perfectly tight to the text is rendered.
The code above simply loads a BitmapFont previously loaded inside the game assets manager.
Then a font scale is applied...I guess it could be added inside a skin property
Anyway...This is the best solution for me.
I'm still using a stage with a ScalingViewport, in this way I have not to use pixels as unit and all the dimensions are scaled to fill the device screen.
Bye,
Luca

How to create a "clicking effect" on a 3d-object (3d-cube) in Unity3d?

I have a 3d-object (cube), which I want to use as a button. I've written the code in order to detect, if the cube was pressed but it doesn't look like it was pressed, since it lacks the "clicking animation". How can I create a clicking animation on my 3d-object ?
A good idea is to play an aninimation which skrinks the cube a bit and releases it immediately afterwards. The handler code you want to execute on a click might block the game loop, e.g. when you load a level. Then it might be useful to load the level aysnchronously to be able to see the animation. Or you execute the handler code after the animation. Or you play the scale down animation on the press event and the scale up animation on the release event.
Technically you can use the build in animation editor, the Update() method, start a coroutine or use the assets iTween or HOTween.
http://docs.unity3d.com/ScriptReference/Transform-localScale.html
Let me know if you like the idea or questions arise.
Unity makes it easier now to do this using Unity Canvas UI. Instead of real 3d buttons, you could place a canvas UI in world space at the location where you want the buttons. Add a UI Panel to the canvas then add a UI Button.
Now, you have out of the box several clicking effects. The default it color tint, but you can choose sprite swap, or animation.
If you do want animation, when you select button animation it will create an animator for you. Click on your UI button Game Object in the scene hierarchy and open the animation window. You can choose Pressed animation from the drop down, and press RECORD button, then edit your buttons scale, say make it 0.75 for x,y,z. Now when you click on the button it will animate a cool scale down for you.
Sorry, I know that is a lot of information dumped! But you will find it pretty great once you start working with it in world space.
You can scale it down a tiny bit once click happen. For example:
void OnMouseDown() {
this.transform.localScale += new Vector3(0.05f, 0.05f, 0.05f);
}
Then after click scale it back to the original size.
Perhaps look into iTween (free on Unity Asset store).
Its very easy to use and you can produce some nice looking animations.
you can scale it when pressed or just change the color a little bit. On mouse up, rescale or recolor it.
void OnMouseDown()
{
transform.localScale -= new Vector3(0.05, 0.05 , 0);
//or
transform.GetComponent<SpriteRenderer>().color += new Color(40,40,40);
}
void OnMouseUp()
{
transform.localScale += new Vector3(0.05, 0.05 , 0);
//or
transform.GetComponent<SpriteRenderer>().color -= new Color(40,40,40);
}
You can implement your button using new Event system of unity. Here are the functions you can implement :
public class ExampleClass : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IPointerClickHandler, IPointerEnterHandler, IPointerExitHandler
{
public void OnPointerEnter(PointerEventData eventData)
{
//it is the function when you hover your mouse to the object
//You can change the color of your object to make your users
//understand that it is not just a cube but also a clickable item
}
public void OnPointerExit(PointerEventData eventData)
{
//You can revert your color back to its original
}
public void OnPointerDown (PointerEventData eventData)
{
//You can play with local scale as suggested by other answers here
}
public void OnPointerUp (PointerEventData eventData)
{
// Revert back the changes you made at onPointerDown
}
public void OnPointerClick (PointerEventData eventData)
{
//Use here for operations when your button is clicked
}
}

Proper use of Unity 4.6 MoveTowards

I have been working on this for several days without success. I made a sprite animation of a bird flapping it's wings. I want to make the bird fly to a specific spot in a tree. The tree is an image, which has a child image with the animation attached. The animation works fine, but I want to move it to a branch on the tree. The class listed below is attached to the child image, but the bird doesn't move toward the branch.
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class FlyBird : MonoBehaviour {
public Transform target; // Target is empty game object defined in the inspector
public float MoveSpeed; // Set to 10 in the inspector
// Script is attached to an Image object and the child of the image is a sprite animation
void FixedUpdate()
{
transform.position = Vector2.MoveTowards(transform.position, target.position, MoveSpeed * Time.deltaTime);
Debug.Log(transform.position.x);
}
}
I don't know what your current behaviour is, but a possibility is that you're moving on FixedUpdate(), so you should use Time.fixedDeltaTime instead of Time.deltaTime
You're using an UI Image, if I got correctly after your edit.
For this type of object, you should use its RectTransform instead of Transform.
Try this:
rectTransform.position = Vector2.MoveTowards(rectTransform.position, target.rectTransform.position, MoveSpeed * Time.deltaTime);
Supposing you can get rectTransform from target object, of course. Another way could be to manipulate rectTransform.anchoredPosition.
Check more information about this type of Rect Transform here: http://docs.unity3d.com/460/Documentation/ScriptReference/RectTransform.html

Resources