rotate a texture2d till 540 degrees with touchmove - unity3d

I have a texture 2d on my gui screen. I want to rotate this texture till +540 and -540 degrees with finger touch rotate. Beyond this limit it should stop rotating.
can any1 help??

I believe that you can't rotate GUI texture. I suppose the best way to do what you want is to assign a plane as a child to camera facing it, and rotate that plane as you want.

public Texture2D steering;
public static TouchControl Instance;
public float angleRotate=0f;
public float carRotation=0f;
public int finger;
private Matrix4x4 savedMatrix;
private float steerAngleRad;
public float steerAngleDeg;
private float steerAngleRadTemp;
public float steerAngleDegTemp;
private float dx=0f;
private float dy=0f;
private int i;
private float newAngle =0f;
private float initAngle;
private float rotationLimit=540f;
public float secondWheelRot=0f;
private float preRotDeg=0f;
private float angleDiff=0f;
private bool clockWheel=false;
private bool onlyOnce=false;
private Vector2 steeringPos;
private Vector2 centre;
private bool inXRange=false;
private bool inYRange=false;
// private bool moving=false;
private float steeringWidth=0f;
private float steeringHeight=0f;
private float gobackSpeed=20f;
void Start()
{
Instance=this;
i=0;
finger=3;
steeringPos=new Vector2(Screen.width*0.025f,Screen.height*0.68f);
steeringWidth=Screen.width*0.12f;
steeringHeight=steeringWidth;
centre = new Vector2(steeringPos.x + steeringWidth / 2, steeringPos.y + steeringHeight / 2);
}
void Update()
{
if(Input.touchCount>0 && (!PauseButton.pauseFlag && !DamageBar.Instance.levelLost && !GameTimer.Instance.levelLost && !CommonIndicator.Instance.levelComplete))
{
for(i=0;i< Input.touchCount; ++i)
{
if(Input.GetTouch(i).position.x > 0f && Input.GetTouch(i).position.x < steeringWidth+Screen.width*0.1f)
{
inXRange=true;
}
else
{
inXRange=false;
}
if(Input.GetTouch(i).position.y > 0f && Input.GetTouch(i).position.y < Screen.height-(steeringPos.y))
{
inYRange=true;
}
else
{
inYRange=false;
}
///////////////if touch is in the range/////////////////////
if(inXRange && inYRange)
{
if(Input.GetTouch(i).phase==TouchPhase.Began)
{
finger=Input.touches[i].fingerId;
dx=Input.GetTouch(i).position.x-centre.x;
dy=Input.GetTouch(i).position.y-(Screen.height-centre.y);
steerAngleRadTemp=Mathf.Atan2(dy,dx);
steerAngleDegTemp=-steerAngleRadTemp*Mathf.Rad2Deg;
}
if((Input.GetTouch(i).phase==TouchPhase.Stationary || Input.GetTouch(i).phase==TouchPhase.Moved))
{
preRotDeg=newAngle;
if(preRotDeg<-180f && preRotDeg>-360f)
{
preRotDeg+=360f;
}
if(preRotDeg>180f && preRotDeg<360f)
{
preRotDeg-=360f;
}
dx=Input.GetTouch(i).position.x-centre.x;
dy=Input.GetTouch(i).position.y-(Screen.height-centre.y);
steerAngleRad=Mathf.Atan2(dy,dx);
steerAngleDeg=-steerAngleRad*Mathf.Rad2Deg;
angleRotate=steerAngleDeg-steerAngleDegTemp;
newAngle=angleRotate;
if(newAngle<-180f && newAngle>-360f)
{
newAngle+=360f;
}
if(newAngle>180f && newAngle<360f)
{
newAngle-=360f;
}
if(!onlyOnce)
{
onlyOnce=true;
if(newAngle>preRotDeg)
clockWheel=true;
else
clockWheel=false;
}
if(clockWheel && preRotDeg>0f && newAngle < 0f)
{
clockWheel=true;
}
else if(clockWheel && preRotDeg<0f && newAngle >0f)
{
clockWheel=true;
}
else if(!clockWheel && preRotDeg>0f && newAngle <0f)
{
clockWheel=false;
}
else if(!clockWheel && preRotDeg<0f && newAngle >0f)
{
clockWheel=false;
}
else if(newAngle>preRotDeg)
{
clockWheel=true;
}
else if(newAngle<preRotDeg)
{
clockWheel=false;
}
if(Mathf.Abs(newAngle)>Mathf.Abs(preRotDeg))
{
angleDiff=Mathf.Abs(newAngle)-Mathf.Abs(preRotDeg);
}
else
{
angleDiff=Mathf.Abs(preRotDeg)-Mathf.Abs(newAngle);
}
if(clockWheel)
{
carRotation+=angleDiff;
secondWheelRot+=angleDiff;
if(secondWheelRot>rotationLimit)
{
secondWheelRot=rotationLimit;
}
}
else
{
carRotation-=angleDiff;
secondWheelRot-=angleDiff;
if(secondWheelRot<-rotationLimit)
{
secondWheelRot=-rotationLimit;
}
}
}
// else
// {
// steeringToZero();
// }
if(Input.GetTouch(i).phase==TouchPhase.Ended)// && Input.touches[i].fingerId != AccControl.Instance.finger)
{
onlyOnce=false;
carRotation=0f;
angleRotate=0f;
newAngle=0f;
steeringToZero();
finger=3;
}
}
else if(!AccControl.Instance.onPadTouch && finger==3)
{
steeringToZero();
}
}
}
else if(Input.touchCount==0)
{
steeringToZero();
}
if(Input.touchCount==1 && AccControl.Instance.onPadTouch)
{
steeringToZero();
}
if (Input.GetKeyDown(KeyCode.Escape) && !PauseButton.pauseFlag)
{
Application.LoadLevel("MainMenu");
}
}
void steeringToZero()
{
if(secondWheelRot>0)
{
secondWheelRot-=gobackSpeed/(Input.touchCount+1);
}
else if(secondWheelRot<0)
{
secondWheelRot+=gobackSpeed/(Input.touchCount+1);
}
if(secondWheelRot<gobackSpeed && secondWheelRot>-gobackSpeed)
{
secondWheelRot=0f;
}
}
void OnGUI()
{
savedMatrix = GUI.matrix;
GUIUtility.RotateAroundPivot(carRotation,centre);
GUI.DrawTexture(new Rect(steeringPos.x,steeringPos.y, steeringWidth, steeringHeight), steering);
GUI.matrix = savedMatrix;
}

Related

Unity-Help needed to turn my keyboard and mouse inputs to setup mobile input

Hey so I have this input script working fine for the PC just wanted to try mobile input. Can someone help to turn this script to work with mobile? I haven't tried anything yet first time trying mobile input. Just tell me how to set up this script with mobile and UI components.
QWERTYUIOPASDFGHJKLZXCVBNM
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerInput : MonoBehaviour
{
public Vector2 input
{
get
{
Vector2 i = Vector2.zero;
i.x = Input.GetAxis("Horizontal");
i.y = Input.GetAxis("Vertical");
i *= (i.x != 0.0f && i.y != 0.0f) ? .7071f : 1.0f;
return i;
}
}
public Vector2 down
{
get { return _down; }
}
public Vector2 raw
{
get
{
Vector2 i = Vector2.zero;
i.x = Input.GetAxisRaw("Horizontal");
i.y = Input.GetAxisRaw("Vertical");
i *= (i.x != 0.0f && i.y != 0.0f) ? .7071f : 1.0f;
return i;
}
}
public float elevate
{
get
{
return Input.GetAxis("Elevate");
}
}
public bool run
{
get { return Input.GetKey(KeyCode.LeftShift); }
}
public bool crouch
{
get { return Input.GetKeyDown(KeyCode.C); }
}
public bool crouching
{
get { return Input.GetKey(KeyCode.C); }
}
public KeyCode interactKey
{
get { return KeyCode.E; }
}
public bool interact
{
get { return Input.GetKeyDown(interactKey); }
}
public bool reload
{
get { return Input.GetKeyDown(KeyCode.R); }
}
public bool aim
{
get { return Input.GetMouseButtonDown(1); }
}
public bool aiming
{
get { return Input.GetMouseButton(1); }
}
public bool shooting
{
get { return Input.GetMouseButton(0); }
}
public float mouseScroll
{
get { return Input.GetAxisRaw("Mouse ScrollWheel"); }
}
private Vector2 previous;
private Vector2 _down;
private int jumpTimer;
private bool jump;
void Start()
{
jumpTimer = -1;
}
void Update()
{
_down = Vector2.zero;
if (raw.x != previous.x)
{
previous.x = raw.x;
if (previous.x != 0)
_down.x = previous.x;
}
if (raw.y != previous.y)
{
previous.y = raw.y;
if (previous.y != 0)
_down.y = previous.y;
}
}
public void FixedUpdate()
{
if (!Input.GetKey(KeyCode.Space))
{
jump = false;
jumpTimer++;
}
else if (jumpTimer > 0)
jump = true;
}
public bool Jump()
{
return jump;
}
public void ResetJump()
{
jumpTimer = -1;
}
}
You can use the new input system in Unity (I see that you're using an old one). It's a pretty convenient way to make sure that your input are generalizable for a wide range of input controllers.
https://www.youtube.com/watch?v=Yjee_e4fICc

When the player shoots it is losing life

I'm making a multiplayer game2d and when my player shoots (the gun has a collider too )it's affecting his life and I don't know why.Probably because when the target "hurt" has RPCtarget.all but I don't know with what to change just to affect the others players in the game , not mine. With what I can replace all?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityStandardAssets.CrossPlatformInput;
using Photon.Pun;
using Photon.Realtime;
using Photon;
using UnityEngine.UI;
public class Character : MonoBehaviourPun,IPunObservable
{
Rigidbody2D rb;
float dirX;
[SerializeField]
float moveSpeed = 5f, jumpForce = 400f, bulletSpeed = 500f;
[SerializeField] private float health = 100;
[SerializeField] private Slider slider;
[SerializeField] private Gradient gradient;
[SerializeField] private Image fill;
public Rigidbody2D bulletPrefabs;
Vector3 localScale;
public DeathsCount myCounts;
public Transform barrel;
public Rigidbody2D bullet;
// Use this for initialization
void Start()
{
localScale = transform.localScale;
rb = GetComponent<Rigidbody2D>();
if (photonView.IsMine)
{
myCounts = FindObjectOfType<DeathsCount>();
}
else
{
}
}
public float Health
{
get { return health; }
set
{
health = value;
slider.value = health;
// fill.color = gradient.Evaluate(slider.normalizedValue);
}
}
private void OnTriggerEnter2D(Collider2D col)
{
if (col.gameObject.CompareTag("Hurt"))
{
if (photonView.IsMine)
{
photonView.RPC("Damage", RpcTarget.All);
}
}
if (col.gameObject.tag == "PowerUp")
{
if (photonView.IsMine)
{
var powerup = col.GetComponent<PowerUp>();
powerup.Pickup(this);
}
else
{
}
}
if (col.gameObject.CompareTag("Bullet"))
{
if (photonView.IsMine)
{
photonView.RPC("Damage", RpcTarget.All);
bullet = bulletPrefabs;
}
}
else
{
}
}
[PunRPC]
void Damage()
{
if (Health > 0)
{
Health -= 20;
}
if (Health <= 0) // check health status
{
Health = 0; // make that Heath don't be < 0
if (photonView.IsMine)
{
myCounts.RpcRespawn(); //Here you should to call counter
photonView.transform.position = Vector2.zero;
Health = 100;
}
}
}
// Update is called once per frame
void Update()
{
if (photonView.IsMine)
{
dirX = CrossPlatformInputManager.GetAxis("Horizontal");
if (dirX != 0)
{
barrel.up = Vector3.right * Mathf.Sign(dirX);
}
if (CrossPlatformInputManager.GetButtonDown("Jump"))
Jump();
if (CrossPlatformInputManager.GetButtonDown("Fire1"))
Fire();
}
else
{
}
}
void FixedUpdate()
{
if (photonView.IsMine)
{
rb.velocity = new Vector2(dirX * moveSpeed, rb.velocity.y);
}
}
void Jump()
{
if (photonView.IsMine)
{
if (rb.velocity.y == 0)
rb.AddForce(Vector2.up * jumpForce);
}
}
void Fire()
{
var firedBullet = PhotonNetwork.Instantiate(bullet.name, barrel.position, barrel.rotation).GetComponent<Rigidbody2D>();
firedBullet.AddForce(barrel.up * bulletSpeed);
}
public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
{
if (stream.IsWriting)
{
stream.SendNext(Health);
}
else if (stream.IsReading)
{
Health = (float)stream.ReceiveNext();
}
}
public void SetMaxHealth(int value)
{
if (photonView.IsMine)
{
slider.maxValue = value;
// The property handles the rest anyway
Health = value;
}
}
}
I think you don't really need RPC in this case.
I see your character IPunObservable and, I guess, added to PhotonView. So its health will sync automatically.
You also instantiate bullets with PhotonNetwork, which means, they will sync too and have PhotonView.
So every player has all synchronized bullets and other players.
It means, all that you need is to check if bullet is from other player and set damage locally (don't worry, result will sync) like this :
. . .
private void OnTriggerEnter2D(Collider2D col)
{
if (col.gameObject.CompareTag("Hurt"))
{
// if hurt object is not mine, take damage
if (!col.gameObject.GetPhotonView().isMine)
Damage();
}
if (col.gameObject.tag == "PowerUp")
{
if (photonView.IsMine)
{
var powerup = col.GetComponent<PowerUp>();
powerup.Pickup(this);
}
else
{
}
}
if (col.gameObject.CompareTag("Bullet"))
{
// if bullet is not mine, take damage
if (!col.gameObject.GetPhotonView().isMine)
Damage();
}
else
{
}
}
// no rpc
void Damage()
{
if (!photonView.IsMine) // only player can change his life
return;
if (Health > 0)
{
Health -= 20;
}
if (Health <= 0) // check health status
{
myCounts.RpcRespawn(); //Here you should to call counter
photonView.transform.position = Vector2.zero;
Health = 100;
}
}

Player want to move left and right from single - touch (Unity)

I made the game in Unity Space Shooter. In my Space shooter there is 2 button it work for Left and Right moving. I want when we touch the left button player go to left only in Single Touch same like Right Button also.
This , are the some codes which i used in Game. Please Help me out from this.
TouchControl.cs
using UnityEngine;
using System.Collections;
public class TouchControl : MonoBehaviour {
public GUITexture moveLeft;
public GUITexture moveRight;
public GUITexture fire;
public GameObject player;
private PlayerMovement playerMove;
private Weapon[] weapons;
void Start()
{
playerMove = player.GetComponent<PlayerMovement> ();
}
void CallFire()
{
weapons = player.GetComponentsInChildren<Weapon> ();
foreach (Weapon weapon in weapons) {
if(weapon.enabled == true)
weapon.Fire();
}
}
void Update()
{
// int i = 0;
if(Input.touchCount > 0)
{
for(int i =0; i < Input.touchCount; i++)
{
// if(moveLeft.HitTest(Input.GetTouch(i).position, Camera.main))
// {
// if(Input.touchCount > 0)
// {
// playerMove.MoveLeft();
// }
// }
// if(moveRight.HitTest(Input.GetTouch(i).position, Camera.main))
// {
// if(Input.touchCount > 0)
// {
// playerMove.MoveRight();
// }
// }
// if(moveLeft.HitTest(Input.GetTouch(i).position, Camera.main))
// {
// if(Input.touchCount > 0)
// {
// CallFire();
// }
// }
// Touch t = Input.GetTouch(i);
Touch t = Input.GetTouch (i);
Input.multiTouchEnabled = true;
if(t.phase == TouchPhase.Began || t.phase == TouchPhase.Stationary)
{
if(moveLeft.HitTest(t.position, Camera.main))
{
playerMove.MoveLeft ();
}
if(moveRight.HitTest(t.position, Camera.main))
{
playerMove.MoveRight();
}
}
if(t.phase == TouchPhase.Began)
{
if(fire.HitTest(t.position, Camera.main))
{
CallFire();
}
}
if(t.phase == TouchPhase.Ended)
{
}
}
}
}
}
PlayerMovement.cs
using UnityEngine;
using System.Collections;
public class PlayerMovement : MonoBehaviour {
public float speedMove = 6.0f;
public float bonusTime;
private bool toLeft = false;
private bool toRight = false;
public GameObject shield;
public GUIText bonustimeText;
private bool counting = false;
private float counter;
private Weapon[] addWeapons;
public Sprite strongShip;
public Sprite normalSprite;
public Sprite shieldSprite;
private SpriteRenderer sRender;
private Weapon weaponScript;
void Start () {
counter = bonusTime;
sRender = GetComponent<SpriteRenderer> ();
addWeapons = GetComponentsInChildren<Weapon> ();
foreach (Weapon addWeapon in addWeapons) {
addWeapon.enabled = false;
}
weaponScript = GetComponent<Weapon>();
weaponScript.enabled = true;
}
// Update is called once per frame
void Update () {
if (Input.GetKeyDown (KeyCode.A)) {
toLeft = true;
}
if (Input.GetKeyUp (KeyCode.A)) {
toLeft = false;
}
if (Input.GetKeyDown (KeyCode.D)) {
toRight = true;
}
if (Input.GetKeyUp (KeyCode.D)) {
toRight = false;
}
if (counting) {
counter -= Time.deltaTime;
bonustimeText.text = counter.ToString("#0.0");
}
}
void FixedUpdate()
{
if (toLeft) {
MoveLeft();
}
if (toRight) {
MoveRight();
}
}
public void MoveLeft()
{
transform.Translate(Vector2.right * -speedMove* Time.deltaTime);
}
public void MoveRight()
{
transform.Translate(Vector2.right * speedMove * Time.deltaTime);
}
void OnCollisionEnter2D(Collision2D coll)
{
if (coll.gameObject.tag == "StrongMode") {
Destroy (coll.gameObject);
counting = true;
StrongMode();
Invoke ("Downgrade", bonusTime);
}
if (coll.gameObject.tag == "ShieldMode") {
Destroy (coll.gameObject);
counting = true;
ShieldMode();
Invoke("Downgrade", bonusTime);
}
if (coll.gameObject.tag == "Life") {
GUIHealth gui = GameObject.Find ("GUI").GetComponent<GUIHealth> ();
gui.AddHealth();
SendMessage("AddHp");
SoundHelper.instanceSound.PickUpSound();
Destroy(coll.gameObject);
}
if (coll.gameObject.tag == "Enemy") {
SendMessage("Dead");
}
}
void Downgrade()
{
SoundHelper.instanceSound.BonusDownSound ();
counting = false;
bonustimeText.text = "";
counter = bonusTime;
sRender.sprite = normalSprite;
weaponScript.enabled = true;
foreach (Weapon addWeapon in addWeapons) {
addWeapon.enabled = false;
}
weaponScript.enabled = true;
shield.SetActive (false);
}
void StrongMode()
{
SoundHelper.instanceSound.BonusUpSound ();
sRender.sprite = strongShip;
foreach (Weapon addWeapon in addWeapons) {
addWeapon.enabled = true;
}
weaponScript.enabled = false;
}
void ShieldMode()
{
SoundHelper.instanceSound.BonusUpSound ();
sRender.sprite = shieldSprite;
shield.SetActive (true);
}
// void OnDestroy()
// {
// bonustimeText.text = "";
// }
}
In the Player Controller script Create:
public Vector3 playerDirection = Vector3.zero;
Then in touch control instead of:
if (moveLeft.HitTest(Input.GetTouch(i).position, Camera.main))
{
if (Input.touchCount > 0)
{
playerMove.MoveLeft();
}
}
if (moveRight.HitTest(Input.GetTouch(i).position, Camera.main))
{
if (Input.touchCount > 0)
{
playerMove.MoveRight();
}
}
Use:
if (moveLeft.HitTest(Input.GetTouch(i).position, Camera.main))
{
if (Input.touchCount > 0)
{
playerMove.playerDirection = Vector3.left;
}
}
if (moveRight.HitTest(Input.GetTouch(i).position, Camera.main))
{
if (Input.touchCount > 0)
{
playerMove.playerDirection = Vector3.right;
}
}
Then in the Update method of Player Controller use:
transform.Translate(playerDirection * speedMove * Time.deltaTime);
public class PlayerController {
public EPlayerState playerState = EPLayerState.Idle;
void Update () {
// If click right button
playerState = EPlayerState.MoveRight;
// Else if click left button
playerState = EPlayerState.MoveLeft
if (playerState == EPlayerState.MoveRight)
// Move player right;
if (playerState == EPlayerState.MoveLeft
// Move player right;
}
}
public enum EPlayerState {
Idle,
MoveRight,
MoveLeft
}
You can also use something like a boolean called isRight, move right when it's true and left when it's false. Then when you click left or right button just change the variable.
`using UnityEngine;
public class HalfScreenTouchMovement : MonoBehaviour
{
private float screenCenterX;
private void Start()
{
// save the horizontal center of the screen
screenCenterX = Screen.width * 0.5f;
}
private void Update()
{
// if there are any touches currently
if(Input.touchCount > 0)
{
// get the first one
Touch firstTouch = Input.GetTouch(0);
// if it began this frame
if(firstTouch.phase == TouchPhase.Began)
{
if(firstTouch.position.x > screenCenterX)
{
// if the touch position is to the right of center
// move right
}
else if(firstTouch.position.x < screenCenterX)
{
// if the touch position is to the left of center
// move left
}
}
}
}
}`
May be helpfull
create script. for example player.cs
public class PlayerController : MonoBehaviour
{
bool swipeRight = false;
bool swipeLeft = false;
bool touchBlock = true;
bool canTouchRight = true;
bool canTouchLeft = true;
void Update()
{
swipeLeft = Input.GetKeyDown("a") || Input.GetKeyDown(KeyCode.LeftArrow);
swipeRight = Input.GetKeyDown("d") || Input.GetKeyDown(KeyCode.RightArrow);
TouchControl();
if(swipeRight) //rightMove logic
else if(swipeLeft) //leftMove logic
}
void TouchControl()
{
if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Moved && touchBlock == true)
{
touchBlock = false;
// Get movement of the finger since last frame
var touchDeltaPosition = Input.GetTouch(0).deltaPosition;
Debug.Log("touchDeltaPosition "+touchDeltaPosition);
if(touchDeltaPosition.x > 0 && canTouchRight == true)
{
//rightMove
swipeRight = true; canTouchRight = false;
Invoke("DisableSwipeRight",0.2f);
}
else if(touchDeltaPosition.x < 0 && canTouchLeft == true)
{
//leftMove
swipeLeft = true; canTouchLeft = false;
Invoke("DisableSwipeLeft",0.2f);
}
}
}
void DisableSwipeLeft()
{
swipeLeft = false;
touchBlock = true;
canTouchLeft = true;
}
void DisableSwipeRight()
{
swipeRight = false;
touchBlock = true;
canTouchRight = true;
}
}

How to program custom buttons to navigate through scroll view created with Scroll Rect combined with a Mask

I have a shop GUI, its content in a srollview created with Scroll Rect and Mask combination and can be scrolled down and up.
Right now, the scroll view scrolls by clicking and dragging with the mouse anywhere in scroll view area, or by interacting with a vertical scrollbar.
How do I use custom up and down buttons (circled in red on attached image below) to make the scroll happen?
Copy the following script to your project and apply ScrollRectSnap script to your scroll view . Know if you have done this to make your scroll view snap on button click simply do the following link UpArrowPressed and DownArrowPressed with your up and down buttons and do not forget to check Snap In V parameter in inspector of ScrollRectSnap if you have vertical scrollview and also do not get confused by snapper.DraggedOnRight() call in your DownArrowPressed function as if you have checked Snap In V parameter it will then act like snap down and similler thing with snapper.DraggedOnLeft() other parameters you can set according to your requirment you will have to play with values in order to get it according to your requirments.
public void UpArrowPressed()
{
ScrollRectSnap snapper = GetComponentInChildren<ScrollRectSnap>();
snapper.DraggedOnLeft();
}
public void DownArrowPressed()
{
ScrollRectSnap snapper = GetComponentInChildren<ScrollRectSnap>();
snapper.DraggedOnRight();
}
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using System;
public class ScrollRectSnap : MonoBehaviour
{
float[] points;
[Tooltip("how many screens or pages are there within the content (steps)")]
public int screens = 1;
[Tooltip("How quickly the GUI snaps to each panel")]
public float snapSpeed;
public float inertiaCutoffMagnitude;
float stepSize;
ScrollRect scroll;
bool LerpH;
float targetH;
[Tooltip("Snap horizontally")]
public bool snapInH = true;
bool LerpV;
float targetV;
[Tooltip("Snap vertically")]
public bool snapInV = true;
public string controllTag;
bool dragInit = true;
int dragStartNearest;
float horizontalNormalizedPosition;
float verticalNormalizedPosition;
public static event Action<int,int> OnEndReached;
public static event Action<int,int,string> OnEndReachedWithTag;
// Use this for initialization
void Start()
{
Init();
// SnapToSelectedIndex(0);
}
void Init()
{
scroll = gameObject.GetComponent<ScrollRect>();
scroll.inertia = true;
if (screens > 0)
{
points = new float[screens];
stepSize = (float)Math.Round(1 / (float)(screens - 1),2);
for (int i = 0; i < screens; i++)
{
points[i] = i * stepSize;
}
}
else
{
points[0] = 0;
}
}
void OnEnable()
{
}
void Update()
{
horizontalNormalizedPosition = scroll.horizontalNormalizedPosition;
verticalNormalizedPosition = scroll.verticalNormalizedPosition;
if (LerpH)
{
scroll.horizontalNormalizedPosition = Mathf.Lerp(scroll.horizontalNormalizedPosition, targetH, snapSpeed * Time.deltaTime);
if (Mathf.Approximately((float)Math.Round(scroll.horizontalNormalizedPosition,2), targetH))
{
LerpH = false;
int target = FindNearest(scroll.horizontalNormalizedPosition, points);
// Debug.LogError("Target : " + target);
if (target == points.Length-1)
{
if (OnEndReached != null)
{
OnEndReached(1,target);
}
if(OnEndReachedWithTag != null)
{
OnEndReachedWithTag(1,target,controllTag);
}
}
else if (target == 0)
{
if (OnEndReached != null)
{
OnEndReached(-1,target);
}
if(OnEndReachedWithTag != null)
{
OnEndReachedWithTag(-1,target,controllTag);
}
}
else
{
if (OnEndReached != null)
{
OnEndReached(0,target);
}
if(OnEndReachedWithTag != null)
{
OnEndReachedWithTag(0,target,controllTag);
}
}
}
}
if (LerpV)
{
scroll.verticalNormalizedPosition = Mathf.Lerp(scroll.verticalNormalizedPosition, targetV, snapSpeed * Time.deltaTime);
if (Mathf.Approximately(scroll.verticalNormalizedPosition, targetV))
{
LerpV = false;
}
}
}
public void DragEnd()
{
int target = FindNearest(scroll.horizontalNormalizedPosition, points);
if (target == dragStartNearest && scroll.velocity.sqrMagnitude > inertiaCutoffMagnitude * inertiaCutoffMagnitude)
{
if (scroll.velocity.x < 0)
{
target = dragStartNearest + 1;
}
else if (scroll.velocity.x > 1)
{
target = dragStartNearest - 1;
}
target = Mathf.Clamp(target, 0, points.Length - 1);
}
if (scroll.horizontal && snapInH )
{
targetH = points[target];
LerpH = true;
}
if (scroll.vertical && snapInV && scroll.verticalNormalizedPosition > 0f && scroll.verticalNormalizedPosition < 1f)
{
targetH = points[target];
LerpH = true;
}
dragInit = true;
}
public void OnDrag()
{
if (dragInit)
{
if (scroll == null)
{
scroll = gameObject.GetComponent<ScrollRect>();
}
dragStartNearest = FindNearest(scroll.horizontalNormalizedPosition, points);
dragInit = false;
}
LerpH = false;
LerpV = false;
}
int FindNearest(float f, float[] array)
{
float distance = Mathf.Infinity;
int output = 0;
for (int index = 0; index < array.Length; index++)
{
if (Mathf.Abs(array[index] - f) < distance)
{
distance = Mathf.Abs(array[index] - f);
output = index;
}
}
return output;
}
public void DraggedOnLeft()
{
OnDrag();
if (scroll.horizontal && snapInH && scroll.horizontalNormalizedPosition > -0.001f && scroll.horizontalNormalizedPosition < 1.001f)
{
// Debug.Log("Before Press, LerpH : " + LerpH);
if (dragStartNearest < points.Length-1)
{
targetH = points[dragStartNearest+1];
LerpH = true;
}
else
{
targetH = points[dragStartNearest];
LerpH = true;
}
// Debug.Log("After Press, LerpH : " + LerpH);
}
if (scroll.vertical && snapInV && scroll.verticalNormalizedPosition > 0f && scroll.verticalNormalizedPosition < 1f)
{
if (dragStartNearest < points.Length-1)
{
targetV = points[dragStartNearest+1];
LerpV = true;
}
else
{
targetV = points[dragStartNearest];
LerpV = true;
}
}
dragInit = true;
}
public void DraggedOnRight()
{
OnDrag();
if (scroll.horizontal && snapInH && scroll.horizontalNormalizedPosition > -0.001f && scroll.horizontalNormalizedPosition < 1.001f)
{
if (dragStartNearest>0)
{
targetH = points[dragStartNearest-1];
LerpH = true;
}
else
{
targetH = points[dragStartNearest];
LerpH = true;
}
}
if (scroll.vertical && snapInV && scroll.verticalNormalizedPosition > 0f && scroll.verticalNormalizedPosition < 1f)
{
if (dragStartNearest > 0)
{
targetV = points[dragStartNearest-1];
LerpV = true;
}
else
{
targetV = points[dragStartNearest];
LerpV = true;
}
}
dragInit = true;
}
public void SnapToSelectedIndex(int index)
{
if (points == null)
{
Init();
}
dragInit = false;
LerpH = false;
LerpV = false;
targetH = points[index];
LerpH = true;
dragInit = true;
}
}

Unity 2D draggable movement control

I want to add a draggable-movement control thing (attached image) like Fifa mobile game in my 2D app.
I searched a lot for the idea or a basic tutorial or relevant Unity asset. But didn't find one.
Help me with an example or URL.
You can use this if you would like, it works on web and mobile
using UnityEngine;
using System.Collections;
public class JoyStick : MonoBehaviour {
public Texture areaTexture;
public Texture touchTexture;
public Vector2 joystickPosition = new Vector2( 50f,50f);
public Vector2 speed = new Vector2(2,100);
public float zoneRadius=100f;
public float touchSize = 30;
public float deadZone=20;
public float touchSizeCoef=0;
protected Vector2 joystickAxis;
protected Vector2 joystickValue;
public Vector2 joyTouch;
private Vector2 _joystickCenter;
[SerializeField]
private Vector2 _smoothing = new Vector2(20f,20f);
public Vector2 Smoothing
{
get {
return this._smoothing;
}
set {
_smoothing = value;
if (_smoothing.x<0.1f){
_smoothing.x=0.1f;
}
if (_smoothing.y<0.1){
_smoothing.y=0.1f;
}
}
}
private int _joystickIndex=-1;
private bool _enaReset;
private bool _enaZoom;
void Start ()
{
zoneRadius = Screen.width*0.07f;
touchSize = Screen.width*0.07f;
joystickPosition = new Vector2(Screen.width*0.12f,Screen.width*0.12f);
_joystickCenter = joystickPosition;
_enaReset=false;
}
void Update ()
{
if (Application.platform == RuntimePlatform.IPhonePlayer || Application.platform == RuntimePlatform.Android)
{
foreach (Touch touch in Input.touches)
{
if (touch.phase == TouchPhase.Ended || touch.phase == TouchPhase.Canceled)
{
if (_joystickIndex==touch.fingerId){
_joystickIndex=-1;
_enaReset=true;
}
}
if(_joystickIndex==touch.fingerId)
{
OnTouchDown(touch.position);
}
if (touch.phase == TouchPhase.Began)
{
if (((Vector2)touch.position - _joystickCenter).sqrMagnitude < Mathf.Pow((zoneRadius+touchSizeCoef/2),2))
{
_joystickIndex = touch.fingerId;
}
}
}
UpdateJoystick();
if(_enaReset)
{
ResetJoystick();
}
}
else
{
if (Input.GetButtonUp ("Fire1"))
{
_joystickIndex=-1;
_enaReset=true;
}
if(_joystickIndex==1)
{
OnTouchDown(Input.mousePosition);
}
if (Input.GetButtonDown ("Fire1") )
{
if (((Vector2)Input.mousePosition - _joystickCenter).sqrMagnitude <Mathf.Pow( (zoneRadius+touchSizeCoef/2),2))
{
_joystickIndex = 1;
}
}
if(_enaReset)
{
ResetJoystick();
}
UpdateJoystick();
}
}
private void UpdateJoystick()
{
if (joyTouch.sqrMagnitude>deadZone*deadZone)
{
joystickAxis = Vector2.zero;
if (Mathf.Abs(joyTouch.x)> deadZone)
{
joystickAxis = new Vector2( (joyTouch.x -(deadZone*Mathf.Sign(joyTouch.x)))/(zoneRadius-touchSizeCoef-deadZone),joystickAxis.y);
}
else
{
joystickAxis = new Vector2( joyTouch.x /(zoneRadius-touchSizeCoef),joystickAxis.y);
}
if (Mathf.Abs(joyTouch.y)> deadZone)
{
joystickAxis = new Vector2( joystickAxis.x,(joyTouch.y-(deadZone*Mathf.Sign(joyTouch.y)))/(zoneRadius-touchSizeCoef-deadZone));
}
else{
joystickAxis = new Vector2( joystickAxis.x,joyTouch.y/(zoneRadius-touchSizeCoef));
}
}
else{
joystickAxis = new Vector2(0,0);
}
Vector2 realvalue = new Vector2( speed.x*joystickAxis.x,speed.y*joystickAxis.y);
joystickValue=realvalue;
//print(realvalue);
}
void OnTouchDown(Vector2 position)
{
joyTouch = new Vector2( position.x, position.y) - _joystickCenter;
if ((joyTouch/(zoneRadius-touchSizeCoef)).sqrMagnitude > 1)
{
joyTouch.Normalize();
joyTouch *= zoneRadius-touchSizeCoef;
}
//print(joyTouch);
}
private void ResetJoystick()
{
if (joyTouch.sqrMagnitude>0.1)
{
joyTouch = new Vector2( joyTouch.x - joyTouch.x*_smoothing.x*Time.deltaTime, joyTouch.y - joyTouch.y*_smoothing.y*Time.deltaTime);
}
else{
joyTouch = Vector2.zero;
_enaReset=false;
}
}
void OnGUI()
{
GUI.DrawTexture( new Rect(_joystickCenter.x -zoneRadius ,Screen.height- _joystickCenter.y-zoneRadius,zoneRadius*2,zoneRadius*2), areaTexture,ScaleMode.ScaleToFit,true);
GUI.DrawTexture( new Rect(_joystickCenter.x+(joyTouch.x -touchSize) ,Screen.height-_joystickCenter.y-(joyTouch.y+touchSize),touchSize*2,touchSize*2), touchTexture,ScaleMode.ScaleToFit,true);
}
}