Move camera with button in unity - c#

I want move Main Camera with button. Its my game play :
its my scene:
want when click in button, main camera move to right in another pic.
This is my script for button:
public void Uss(GameObject camera) {
Vector3 temp = transform.position;
temp.x += 0.1f;
camera.transform.position = temp;
}

In your script, the button is moved, not the camera. You should move the GameObject of the main camera instead.
Transform cameraTransform;
void Start()
{
cameraTransform = Camera.main.gameObject.transform;
}
public void Update()
{
cameraTransform.Translate(7, 0, 0);
}
But I recommend you write the logic in the onClick handler of the button like below.
Attach a script to the button GameObject
float step = 100;//find a proper value for this
void Start()
{
Button b = gameObject.GetComponent<Button>();
b.onClick.AddListener(
()=>
{
Camera.main.gameObject.transform.Translate(step, 0, 0);
}
);
}
The step value is dependent on the size of your pictures.
I haven't tested the script but it should work in that way.

Related

Script keeps Vector2 values after the scene gets reloaded. Setting new X,Y values in Awake() or Start() functions doesn't work after second load

I'm making a game for android/IOS and I'm using a Vector2 to move the player diagonally by pressing/tapping two buttons(left,right). My problem is that after the player collides with an object and dies, and the scene reloads. The X,Y values equals the values before the reload but i want them to be 0, 0.
I've fiddled around with these three scripts below. It might be something to do with the player object becoming inactive. (Sorry if it's messy first time posting)
//from player movement script
private void Awake()
{
moveChange = new Vector2(0.0f, 0.0f);
}
void Start()
{
rb = GetComponent<Rigidbody2D>();
}
void FixedUpdate()
{
Vector3 movement = moveChange * speed * Time.deltaTime;
rb.MovePosition(transform.position + movement);
}
public void ClickR()
{
moveChange = new Vector2(0.5f, 1.0f);
}
public void ClickL()
{
moveChange = new Vector2(-0.5f, 1.0f);
}
//from collision script
private void OnTriggerEnter2D(Collider2D other)
{
GameObject e = Instantiate(explosion) as GameObject;
e.transform.position = transform.position;
this.gameObject.SetActive(false);
}
//from reload script
void Update()
{
if (GameObject.FindWithTag("Player") == null)
{
timer += Time.deltaTime;
if (timer > beforeLoading)
{
Scene scene = SceneManager.GetActiveScene();
SceneManager.LoadScene(scene.name);
}
}
}
So the player object doesn't move on the first scene load, as intended, but instantly starts moving to left/right depending on which button has been pressed/tapped before the scene reloads. I've tried to set the X,Y values to 0f, 0f in the Awake() / Start() functions and also in OnTriggerEnter but it didn't work.
One thing I did notice is that if i tap somewhere else on the screen(android) other than the buttons before reloading level the player doesn't move and X, Y is set to 0, 0.
It had nothing to do with the code. I changed the "Event type" on the "Event Trigger" script on the buttons to "PointerDown" instead of "PointerEnter" and now it's working as intended. As simple as that.

Unity3d transform.position not returning the correct value

A little background on what I'm working on : Basically I have a cube model which will be used to generate some terrain structure. All of those gameobjects were created on Runtime by doing :
float yPos = 0f;
float scale = 0.5f;
var robot = GameObject.Instantiate(grassTile) as GameObject;
robot.transform.position = new Vector3(0, yPos, 0);
robot.transform.localScale = new Vector3(scale, scale, scale);
robot.transform.rotation = Quaternion.Euler(-90, 0, 0);
width = robot.GetComponent<Renderer>().bounds.size.z;
for(int i=0;i<5;i++){
yPos += width;
robot = GameObject.Instantiate(grassTile) as GameObject;
robot.transform.position = new Vector3(0, yPos, 0);
robot.transform.localScale = new Vector3(scale, scale, scale);
robot.transform.rotation = Quaternion.Euler(-90, 0, 0);
//attach the script
robot.AddComponent<CubeBehavior>();
}
What's inside the CubeBehavior.cs :
void Start () {
}
// Update is called once per frame
void Update () {
if (Input.touchCount > 0) {
Debug.Log(transform.position);
}
}
What happened is no matter which cube I touch, it will always return the last cube position. Please enlighten me about this problems. Thanks in advance
You have no code that detect which cube was touched.
Input.touches just tells you how many touches are currently detected on the screen.
To detect touches, you will need to do some more work. One of the possible solution is to implement touch event handlers. Example inspired from the doc:
public class CubeBehaviour : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
{
//Detect current clicks on the GameObject (the one with the script attached)
public void OnPointerDown(PointerEventData pointerEventData)
{
//Output the name of the GameObject that is being clicked
Debug.Log(name + " click down at position " + transform.position);
}
//Detect if clicks are no longer registering
public void OnPointerUp(PointerEventData pointerEventData)
{
Debug.Log(name + "No longer being clicked");
}
}
This will need an EventSystem somewhere in your scene. Potentially, you will also need trigger colliders on the cubes, not sure

Moving UI with Screen Space - Camera (Unity)

I want to move an image UI when Canvas is set on Screen Space - Camera
However, nothing seems to work. I've tried the following things:
public void OnDrag(PointerEventData eventData)
{
Vector3 screenPoint = Input.mousePosition;
screenPoint.z = 0.13f; //distance of the plane from the camera
icon.transform.position = Camera.main.ScreenToWorldPoint(screenPoint);
}
Makes the image move out of the screen instantly.
public GameObject Target;
private EventTrigger _eventTrigger;
void Start ()
{
_eventTrigger = GetComponent<EventTrigger>();
_eventTrigger.AddEventTrigger(OnDrag, EventTriggerType.Drag);
}
void OnDrag(BaseEventData data)
{
PointerEventData ped = (PointerEventData) data;
Target.transform.Translate(ped.delta);
}
same story, image dissapires and moves out of the screen.
public void OnDrag(PointerEventData eventData)
{
Vector3 clickedPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
InventoryParent.transform.position = clickedPosition;
}
as the above.
Anyone has idea on how can I do accurate mouse dragging UI with Screen-Space Camera? Doing it with overlay works fine.
Change your UI element RectTransform anchors to:
and add this script to your UI element object:
RectTransform rectT;
void Start()
{
EventTrigger trigger = GetComponent<EventTrigger>();
EventTrigger.Entry entry = new EventTrigger.Entry();
entry.eventID = EventTriggerType.Drag;
entry.callback.AddListener((data) => { OnDragDelegate((PointerEventData)data); });
trigger.triggers.Add(entry);
rectT = GetComponent<RectTransform>();
}
public void OnDragDelegate(PointerEventData data)
{
rectT.anchoredPosition = data.position;
}
You also need the EventTrigger component on your UI element object.

How to Save a UI Image Rotation and Load it When Coming Back from a Different Scene in Unity3D?

In my 2D game the player should be able to rotate a UI Image based on a Mouse Drag function, and then press the "Go" button to start the level, and after this the "Back" button on the level should take the player back to the main scene (the one that has the UI Image), thus the image should be displayed in the same last rotation the player has set for it. Everything works fantastically fine for me except for the part of loading the image rotation. I was able to see the correct rotation value in the console, however I see no rotation on the image when coming back from the other scene. I've been trying to do so many attempts to make it work but not getting any good results. It will be so much appreciated if you help me celebrate my birthday tomorrow!
I hope this will explain better what I am trying to do:
First scene where the square is the UI Image and the Go button is under
After the user drags the image, it gets a new rotation. Then the player clicks the Go button, the rotation is saved and a new scene will be displayed.
And then there is a second scene that has the Back button (it takes the user to the main scene and should display the rotated UI image based on the last user's input). The issue is that there is no rotation shown at all on the UI Image.
And here is the code I have used for the UI Image Rotation:
public static Quaternion rot;
public void OnMouseDrag(){
Vector3 pos = Camera.main.WorldToScreenPoint (transform.position);
Vector3 dir = Input.mousePosition - pos;
float angle = Mathf.Atan2 (dir.y, dir.x) * Mathf.Rad2Deg;
transform.rotation = rot;
rot = Quaternion.AngleAxis (angle, Vector3.forward);
}
And this is the code assigned to the "Go" Button in the first scene:
public void OnClicked(Button button)
{
PlayerPrefs.SetFloat ("PlayerX", ImgRotation.rot.eulerAngles.x);
PlayerPrefs.SetFloat ("PlayerY", ImgRotation.rot.eulerAngles.y);
PlayerPrefs.SetFloat ("PlayerZ", ImgRotation.rot.eulerAngles.z);
Application.LoadLevel ("2");
}
And the code assigned to the "Back" button in the second scene:
public void OnClicked(Button button)
{
Vector3 imgRot;
imgRot = ImgRotation.rot.eulerAngles;
imgRot.x = PlayerPrefs.GetFloat ("PlayerX");
imgRot.y = PlayerPrefs.GetFloat ("PlayerY");
imgRot.z = PlayerPrefs.GetFloat ("PlayerZ");
print (imgRot.z);
Application.LoadLevel ("1");
}
The reason you're not seeing the rotation is because you're never setting it on the actual image object. You can't do this from the back button because the image object won't exist in that scene.
Simply load the settings on Awake instead:
void Awake()
{
Vector3 imgRot;
imgRot.x = PlayerPrefs.GetFloat ("PlayerX");
imgRot.y = PlayerPrefs.GetFloat ("PlayerY");
imgRot.z = PlayerPrefs.GetFloat ("PlayerZ");
transform.rotation = Quaternion.Euler(imgRot);
}
Keep in mind that this setting will be persisted between the game closing down and starting back up. If that's not the behaviour you're after, see below for a possible example on how to persist these sorts of settings between scenes.
Rather than using the PlayerPrefs to store this information between scenes, consider having an object that uses DontDestroyOnLoad to persist the data.
for example, you could have an object in the scene that looks something like this:
public class RotationStorage : public MonoBehaviour
{
private Quaternion m_imageRotation = Quaternion.identity;
void Awake()
{
DontDestroyOnLoad(gameObject);
}
void SetRotation(Quaternion rotation)
{
m_imageRotation = rotation;
}
void OnLevelWasLoaded(int level)
{
if (Application.loadedLevelName == "Your starting scene")
{
GameObject image = GameObject.Find("name of your object");
//If the rotation hasn't been set yet don't set the image' rotation.
if(image != null && m_rotation != Quaternion.identity)
{
image.transform.rotation = m_imageRotation;
}
}
}
}
Then, inside the script on the image you're rotating, you'd keep a reference to the RotationStorage gameObject and store your current rotation in that whenever OnMouseDrag is called:
private RotationStorage m_storage = null;
void Awake()
{
m_storage = FindObjectOfType<RotationStorage>();
}
void OnMouseDrag()
{
Vector3 pos = Camera.main.WorldToScreenPoint (transform.position);
Vector3 dir = Input.mousePosition - pos;
float angle = Mathf.Atan2 (dir.y, dir.x) * Mathf.Rad2Deg;
transform.rotation = rot;
rot = Quaternion.AngleAxis (angle, Vector3.forward);
m_storage.SetRotation(rot);
}
To ensure you don't get duplicate copies of the RotationStorage object, you'd want to set it up in a scene that only ever gets loaded once, i.e. a splash screen on start-up.
So finally I got my problem solved! I have added a boolean static variable in the Back Button Script so whenever the button is pressed and it takes the player to the first scene, the boolean will turn true. And in the other side in the imgRotation Script I have added a Start() function so whenever the scene starts it will rotate the image based on the last user's input.
So this is the BackButtonScript:
public static Vector3 imgRot;
[HideInInspector] public static bool loadRot=false;
public void OnClicked(Button button)
{
imgRot = ImgRotation.rot.eulerAngles;
imgRot.x = PlayerPrefs.GetFloat ("PlayerX");
imgRot.y = PlayerPrefs.GetFloat ("PlayerY");
imgRot.z = PlayerPrefs.GetFloat ("PlayerZ");
loadRot= true;
Application.LoadLevel ("1");
}
And this is the ImgRotation Script:
public static Quaternion rot;
void Start(){
if (BackButtonScript.loadRot == true) {
transform.Rotate(BackButtonScript.imgRot);
}
}
public void OnMouseDrag(){
Vector3 pos = Camera.main.WorldToScreenPoint (transform.position);
Vector3 dir = Input.mousePosition - pos;
float angle = Mathf.Atan2 (dir.y, dir.x) * Mathf.Rad2Deg;
transform.rotation = rot;
rot = Quaternion.AngleAxis (angle, Vector3.forward);
}
Hope it helps! :)

Unity2D: How to check if a sprite is clicked/touched

I am making a 2D platformer in Unity for iOS, and I need to make buttons so the user can move, but for some reason, the script I made is not working. Also, the script I am putting in is just for the Left button, but the Right and Jump scripts work the same way.
Code:
using UnityEngine;
using System.Collections;
public class Left : MonoBehaviour {
public GameObject player;
public GameObject button;
void Start () {
}
void Update () {
if (Input.GetKey (KeyCode.A)) {
player.GetComponent<PlayerAnimator>().animationState = MovementState.moveLeft;
player.transform.position+=Vector3.left / 30;
}
if (Input.touchCount > 0){
foreach(Touch touch in Input.touches){
Collider2D col = button.GetComponent<Collider2D>();
Vector3 tpos = Camera.main.ScreenToWorldPoint(new Vector3(touch.position.x, touch.position.y, 0));
if(col.bounds.Contains(tpos)){
Debug.Log ("left");
player.GetComponent<PlayerAnimator>().animationState = MovementState.moveLeft;
player.transform.position+=Vector3.left / 30;
}
}
}
}
void OnMouseOver(){
Debug.Log ("left");
player.GetComponent<PlayerAnimator>().animationState = MovementState.moveLeft;
player.transform.position+=Vector3.left / 30;
}
void OnMouseUp(){
player.GetComponent<PlayerAnimator> ().animationState = MovementState.idleLeft;
}
}
Don't use OnMouseOver for android application. It isn't usable on touch devices. But instead of it, OnMouseDrag function will work.
void OnMouseDrag(){
Debug.Log ("left");
player.GetComponent<PlayerAnimator>().animationState = MovementState.moveLeft;
player.transform.position+=Vector3.left / 30;
}
Edit: Because OnMouseOver is called when position of mouse is over object but not clicked. Otherwise OnMouseDrag is called when position of mouse is over object and clicked. In mobile devices OnMouseOver situation isn't possible.

Categories