How do I create the Zoom-in and Zoom-out feature in Unity-3d using UI button click?
Solution depends on your specific setup, but this should be a good starting point, if you're using an ortographic Camera. If you're using a perspective camera instead, you should move its Transform's position forward or backwards. I'm also using Mathf.Clamp to restrict the zooming level to a specific range.
using UnityEngine;
using UnityEngine.UI;
public class Zoomer: MonoBehaviour
{
public Button zoomInButton;
public Button zoomOutButton;
public float zoomDelta = 0.1f;
public float minZoom;
public float maxZoom;
Camera cam;
void Start()
{
cam = Camera.main;
}
void OnEnable()
{
zoomInButton.onClick.AddListener(delegate { Zoom(-zoomDelta); });
zoomOutButton.onClick.AddListener(delegate { Zoom(zoomDelta); });
}
void Zoom(float value)
{
float v = Mathf.Clamp(
cam.orthographicSize + value,
minZoom,
maxZoom
);
cam.orthographicSize = v;
}
}
Related
I am trying to make multiple object transparent using a slider but not all at the same time. What is it ,mean is that the selected object should be able to have a transparent shade on it. I have written a code for it. But I need help to identify my mistake or correct me in the code.
Code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class TransparentObject : MonoBehaviour
{
private GameObject objectTotransparent;
public float alpha = 0.5f;
private Material currentMat;
public Slider transparentSlider;
void Awake()
{
transparentSlider.onValueChanged.AddListener(OnSliderChanged);
}
//void Start()
//{
//objectTotransparent = gameObject;
//currentMat = objectTotransparent.GetComponent<Renderer>().material;
//}
void Update()
{
//ChangeAlpha(currentMat, alpha);
Touch touch = Input.GetTouch(0);
if (touch.phase == TouchPhase.Began)
{
Ray ray = Camera.current.ScreenPointToRay(touch.position);
RaycastHit hitObject;
if (Physics.Raycast(ray, out hitObject))
{
objectTotransparent = hitObject.transform.parent.transform.parent.gameObject;
objectTotransparent.GetComponent<Recolour>().SetSelected();
}
}
}
/*void ChangeAlpha(Material mat, float alphaVal)
{
}*/
void OnSliderChanged(float alphaVal)
{
//ChangeAlpha(currentMat, transparentSlider.value);
//Color oldColor = mat.color;
//Color newColor = new Color(oldColor.r, oldColor.g, oldColor.b, alphaVal);
//mat.SetColor("_Color", newColor);
transparentSlider = GUI.HorizontalSlider( Rect(20,135,175,30), transparentSlider, 1, 0);
renderer.material.color.a = transparentSlider;
}
public void Deselect()
{
objectTotransparent.GetComponent<Recolour>().SetOriginalMaterial();
objectTotransparent = null;
transparentSlider.value = alpha;
}
}
In the OnSliderChanged method, try setting the alpha component to transparentSlider.value instead of the Slider object. Here's how you should change the transparency of an object in a simple script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ChangeTransparency : MonoBehaviour
{
//renderer attached to the object that you want to make transparent
public Renderer rend;
//ui slider that you want to use to controll the transparency
public Slider slider;
private void Update()
{
rend.material.color = new Color(
rend.material.color.r,
rend.material.color.g,
rend.material.color.b,
slider.value
);
}
}
NOTE: The material that is applied to the object that you want to make transparent should have its Rendering Mode set to Transparent:
Inspector for the material:
Now you can change the albedo and all the other parameters to mimic your original material.
I can't make my jump and land animations play reliably Currently the jump animation doesn't play and the land animation seems to play randomly.
I've been working with unity 3d for several months but I am new to using animations. I may just be missing some basic information.
At one point the jump animation would play, but only after the player was in the air. How do I make animations play at the right time reliably?
This is my player movement script where I'm currently calling the jump and land animations from.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMvmt : MonoBehaviour
{
public Rigidbody player;
public float sideForce = 5;
public float jumpForce = 5;
public float fallingForce = 10;
public SphereCollider col;
public LayerMask groundLayers;
public Animator jump;
public Animator land;
private void Start()
{
jump = GetComponent<Animator>();
land = GetComponent<Animator>();
}
private void Update()
{
if ( Input.GetKey("a"))
{
player.AddForce(-sideForce, 0, 0);
}
if ( Input.GetKey("d"))
{
player.AddForce(sideForce, 0, 0);
}
if (IsGrounded() && Input.GetKey("w"))
{
jump.SetBool("playJump",true);
Invoke("StopJumpAnimation", .4f);
player.AddForce(0, jumpForce, 0);
}
OncollisionEnter();
if (IsGrounded() == false)
{
player.AddForce(0, -fallingForce, 0);
}
}
private bool IsGrounded()
{
return Physics.CheckCapsule(col.bounds.center,
new Vector3(col.bounds.center.x,
col.bounds.min.y, col.bounds.center.z), col.radius * .9f, groundLayers);
}
void StopJumpAnimation()
{
jump.SetBool("playJump", false);
}
void StopLandAnimation()
{
land.SetBool("playLand", false);
}
void OncollisionEnter()
{
land.SetBool("playLand", true);
Invoke("StopLandAnimation", .3f);
}
}
I can show you pictures of the animator if that helps. I might just need a basic explanation of how to use the animator since I'm new to animation.
So I'm working on a racing game but first need to get my wheel collider and wheel mesh functioning properly but for some reason they don't appear to be in sync. The wheel colliders rotate for steering and for acceleration but the wheel mesh does not follow, instead it stays idle when testing.
This is the code I have used to get the vehicle moving and wheel colliders spinning which is supposedly meant to make the wheel mesh spin also.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
[System.Serializable]
public class AxleCougarInfo {
public WheelCollider LeftWheel;
public GameObject LeftWheelMesh;
public WheelCollider RightWheel;
public GameObject RightWheelMesh;
public bool motor;
public bool steering;
}
public class CougarController : MonoBehaviour {
public List<AxleCougarInfo> axleInfos;
public float maxMotorTorque;
public float maxSteeringAngle;
public void ApplyLocalPositionToVisual(AxleCougarInfo wheelPair)
{
wheelPair.LeftWheelMesh.transform.Rotate (Vector3.left, Time.deltaTime * wheelPair.LeftWheel.rpm * 10, Space.Self);
wheelPair.RightWheelMesh.transform.Rotate (Vector3.right, Time.deltaTime * wheelPair.RightWheel.rpm * 10, Space.Self);
}
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
public void FixedUpdate() {
float motor = maxMotorTorque * Input.GetAxis ("Horizontal");
float steering = maxSteeringAngle * Input.GetAxis ("Vertical");
foreach (AxleCougarInfo axleInfo in axleInfos)
{
if (axleInfo.steering == true)
{
axleInfo.LeftWheel.steerAngle = steering;
axleInfo.RightWheel.steerAngle = steering;
}
if (axleInfo.motor == true)
{
axleInfo.LeftWheel.motorTorque = motor;
axleInfo.RightWheel.motorTorque = motor;
}
}
}
}
I've been through number of answers on this topic, but nothing has seemed to work for my case. I'm trying to detect a mouseDown on a UI element with a canvas renderer which is inside the hierarchy of an object with the canvas on it. I'm new to this, so I'm not sure if the canvas needs to be linked to this canvas renderer or if they have to be on the same object, but the following code is not resulting in the OnPointerDown method being activated.
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System.Collections;
public class Knob : MonoBehaviour, IPointerDownHandler, IPointerUpHandler {
public Slider slider;
public GameObject pivot;
public bool selected;
public float z;
public Image image;
public UtilityClass the;
public float min;
public float max;
void Start () {
z = 90;
Quaternion rotation = Quaternion.Euler (0, 0, z);
pivot.transform.rotation = rotation;
}
void Update() {
Vector3 mousePosition = Camera.main.ScreenToWorldPoint (Input.mousePosition);
if (selected) {
float pivotAngle = the.AngleFrom (the.Heading (pivot.transform.position, mousePosition));
if (pivotAngle >= min && pivotAngle <= max)
z = pivotAngle;
Quaternion rotation = Quaternion.Euler (0, 0, z);
pivot.transform.rotation = rotation;
}
}
public void OnPointerDown(PointerEventData eventData) {
selected = true;
}
public void OnPointerUp(PointerEventData eventData) {
selected = false;
}
}
At the moment I don't have a Collider 2D on the object, but I have "Raycast Target" selected in the Image script. Any help would be appreciated.
Credit to Juan Bayona Beriso I was missing an Event System Component.
So I have 3 same images, but with different colors which I want to cycle in my menu. They are only with different hue/saturations and I want them to slowly reduce their alpha 1 by 1 so that the one behind pops up and then restart the cycle.
I'm trying to set a public image and reduce it's alpha, but it's not smooth.
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class Fading : MonoBehaviour {
public Image image;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update ()
{
//image.CrossFadeAlpha(50, 5, false);
image.GetComponent<CanvasRenderer>().SetAlpha(0.1f);
image.CrossFadeAlpha(10f, 4f, false);
}
}
CrossFadeAlpha should only be called to start the image fade transition, via a button press or similar, as the method works similar to a Coroutine, example (on mouse button press);
public class ImageFade : MonoBehaviour
{
[SerializeField]
private Image m_img;
[SerializeField]
private float m_fadeDuration;
[SerializeField]
private bool m_ignoreTimeScale;
public void Update()
{
if (Input.GetMouseButtonDown(0))
m_img.CrossFadeAlpha(0f, m_fadeDuration, m_ignoreTimeScale);
if (Input.GetMouseButtonDown(1))
m_img.CrossFadeAlpha(1f, m_fadeDuration, m_ignoreTimeScale);
}
}
However if you would prefer to control this functionality manually, you have to take a longer approach. Below you can see that every time the mouse is pressed, the fade multiplier is negated, making it always 1 or -1. This value is then multiplied by the fraction of time needed for this update (before being added to the current alpha value);
Time.deltaTime / m_fadeDuration
As well as this, the boolean m_requiresUpdate, makes sure to avoid unnecessary updates, setting itself to false after the fade is complete.
public class ImageFade : MonoBehaviour
{
[SerializeField]
private Image m_img;
[SerializeField]
private float m_fadeDuration;
[SerializeField]
private bool m_ignoreTimeScale;
private int m_fadeMultiplier;
private float m_alpha;
private bool m_requiresUpdate;
public void Start()
{
m_fadeMultiplier = 1;
m_alpha = 1f;
}
public void Update()
{
//Toggle subtracting/adding
if (Input.GetMouseButtonDown(0))
{
m_fadeMultiplier = -m_fadeMultiplier;
m_requiresUpdate = true;
}
//Update
if (m_requiresUpdate)
{
//Fade
m_alpha = Mathf.Clamp(m_alpha + (m_fadeMultiplier * (Time.deltaTime / m_fadeDuration)), 0f, 1f);
m_img.canvasRenderer.SetAlpha(m_alpha);
//Finished fading
if (m_alpha == 0f || m_alpha == 1f)
m_requiresUpdate = false;
}
}
}
Hope this ties everything together nicely for you.