UnityPC端:缩放移动画面

Posted 凋零叶子

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UnityPC端:缩放移动画面相关的知识,希望对你有一定的参考价值。

文章目录


前言

  本文章内容适用于PC端UCUI,通过鼠标移动与滑动滚轮,进行正交摄像机的移动与缩放。


一、前置修改

1.修改Canvas

1)分离Canvas
 将UI按照是否跟随摄像机移动分离到多个Canvas。

2)修改RenderMode
 不跟随摄像机移动的Canvas设置为WorldSpace。(仅此项,Canvas不会跟随摄像机移动)
 跟随摄像机移动的Canvas设置为其它选项。

3)修改Scale
 RenderMode设置为WorldSpace,需要修改Scale为0.01

4)修改order in Layer
 该数值越大,显示越靠上,按需调整即可。

2.修改Camera


  正交摄像机的视口大小Size 的含义:输出的游戏画面的高度对应 2* size 个 Unity 单位。(一个单位通常为100个像素)


二、代码实现

1.缩放

代码如下:

 private void ZoomCamera()
    
        float zoomValue = Input.GetAxis("Mouse ScrollWheel");
        if (zoomValue != 0)
        
            NowSize = Camera.main.orthographicSize + zoomValue * ZoomSpeed;
            NowSize = Mathf.Min(NowSize, MaxScale);
            NowSize = Mathf.Max(NowSize, MinScale);

            Camera.main.orthographicSize = NowSize;        
        
    

2.移动

代码如下:

private void MoveCamera()
    
        float moveX = 0, moveY = 0;

        float x = Input.mousePosition.x;
        float y = Input.mousePosition.y;

        if (x < JudgeX)//判断鼠标水平方向 是否进入移动判定区域
        
            moveX = -MoveX;
        
        else if (x > ScreenSize.x - JudgeX)
        
            moveX = MoveX;
        
        else
        
            moveX = 0;
        

        if (y < JudgeY)//判断鼠标垂直方向 是否进入移动判定区域
        
            moveY = -MoveY;
        
        else if (y > ScreenSize.y - JudgeY)
        
            moveY = MoveY;
        
        else
        
            moveY = 0;
        

        Vector3 endPos = Return_EndPos(moveX, moveY);//摄像机应移动距离
   
        this.transform.position = Vector3.Lerp(this.transform.position, endPos, MoveSpeed * Time.deltaTime);//插值移动,避免显示卡顿       
    

    private Vector3 Return_EndPos(float moveX, float moveY)
    
        float endX = moveX + this.transform.position.x;
        float endY = moveY + this.transform.position.y;

        float zoomScale = (NowSize - MinScale) / (MaxScale - MinScale);//当前缩放比例 处于 最小缩放比例与最大缩放比例中的 位置

        endX = Mathf.Min(Mathf.Max(MinX + zoomScale * JudgePosX, endX), MaxX - zoomScale * JudgePosX);
        endY = Mathf.Min(Mathf.Max(MinY + zoomScale * JudgePosY, endY), MaxY - zoomScale * JudgePosY);//将摄像机最终位置,调整为极限位置内
        Vector3 endPos = new Vector3(endX, endY, 0);

        return endPos;
    

3.总览

代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MoveAndZoomCamera : MonoBehaviour 
    [Header("缩放")]
    public float ZoomSpeed = 5;

    private float MinScale = 5.4f;
    private float MaxScale = 10.8f;
    private float NowSize = 5.4f;

    [Header("移动")]
    public float JudgeX = 5f;
    public float MoveX = 5f;

    public float JudgeY = 5f;
    public float MoveY = 5f;
    public float MoveSpeed = 1;

    private Vector3 StartPos = new Vector3(0, 0, 0);
    private Vector2 ScreenSize = new Vector2(1920, 1080);
    private Vector2 BgSize = new Vector2(3840, 2160);

    private float MinX, MinY, MaxX, MaxY;
    private bool IsZoom = false;

    private float JudgePosX, JudgePosY;

    private void Start()
    
        this.transform.position = StartPos;


        MinX = -(BgSize.x - ScreenSize.x) / 2 / 100;
        MaxX = (BgSize.x - ScreenSize.x) / 2 / 100;
        MinY = -(BgSize.y - ScreenSize.y) / 2 / 100;
        MaxY = (BgSize.y - ScreenSize.y) / 2 / 100;//最小缩放比例下 摄像机紧贴背景上下左右边缘时 的坐标 

        JudgePosX = (MaxScale - MinScale) / ScreenSize.y * ScreenSize.x;
        JudgePosY = MaxScale - MinScale;//最小缩放比例 与 最大缩放比例 摄像机可移动距离 
    

    private void Update()
    
        ZoomCamera();
        MoveCamera();
    

    private void ZoomCamera()
    
        float zoomValue = Input.GetAxis("Mouse ScrollWheel");
        if (zoomValue != 0)//判断是否滑动 鼠标滑轮
        
            NowSize = Camera.main.orthographicSize + zoomValue * ZoomSpeed;
            NowSize = Mathf.Min(NowSize, MaxScale);
            NowSize = Mathf.Max(NowSize, MinScale);

            Camera.main.orthographicSize = NowSize;
            IsZoom = true;//正在缩放
        
        else
        
            IsZoom = false;//当前未缩放
        
    

    private void MoveCamera()
    
        float moveX = 0, moveY = 0;

        float x = Input.mousePosition.x;
        float y = Input.mousePosition.y;

        if (x < JudgeX)//判断鼠标水平方向上 是否进入移动判定区域
        
            moveX = -MoveX;
        
        else if (x > ScreenSize.x - JudgeX)
        
            moveX = MoveX;
        
        else
        
            moveX = 0;
        

        if (y < JudgeY)//判断鼠标垂直方向上 是否进入移动判定区域
        
            moveY = -MoveY;
        
        else if (y > ScreenSize.y - JudgeY)
        
            moveY = MoveY;
        
        else
        
            moveY = 0;
        

        Vector3 endPos = Return_EndPos(moveX, moveY);//摄像机应移动距离

        if (IsZoom)//当前处于缩放状态
        
            this.transform.position = endPos;//直接调整位置,避免显示背景之外的区域
        
        else
        
            this.transform.position = Vector3.Lerp(this.transform.position, endPos, MoveSpeed * Time.deltaTime);//插值移动,避免显示卡顿
        
    

    private Vector3 Return_EndPos(float moveX, float moveY)
    
        float endX = moveX + this.transform.position.x;
        float endY = moveY + this.transform.position.y;

        float zoomScale = (NowSize - MinScale) / (MaxScale - MinScale);//当前缩放比例 处于 最小缩放比例与最大缩放比例中的 位置

        endX = Mathf.Min(Mathf.Max(MinX + zoomScale * JudgePosX, endX), MaxX - zoomScale * JudgePosX);
        endY = Mathf.Min(Mathf.Max(MinY + zoomScale * JudgePosY, endY), MaxY - zoomScale * JudgePosY);//将摄像机最终位置,调整为极限位置内
        Vector3 endPos = new Vector3(endX, endY, 0);

        return endPos;
    



参考

Unity Camera详述

Unity 单位和图片像素关系

Unity 鼠标滚轮放大缩小

Unity Vector3.Lerp()方法的理解

Unity 实现放大缩小以及相机位置平移实现拖拽效果

移动端双指缩放旋转

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>移动端双指缩放、旋转</title>

<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0,maximum-scale=1.0">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">

<style>
#div1{
width:200px;
height:200px;
background: red;
margin: 50px auto;
font-size: 40px;
color: #fff;
}
</style>
<script>
function a2d(n){
return n*180/Math.PI;
}
document.addEventListener(‘DOMContentLoaded‘,function(){
var oDiv=document.querySelector(‘#div1‘);

var x=0;
var y=0;
var d=0;
var s=1;

oDiv.addEventListener(‘touchstart‘,function(ev){
var oldX=x;
var oldY=y;
var oldD=d;
var oldS=s;

function getT(ev){
var x1=ev.targetTouches[0].pageX;
var y1=ev.targetTouches[0].pageY;

var x2=ev.targetTouches[1].pageX;
var y2=ev.targetTouches[1].pageY;

var x=(x1+x2)/2;
var y=(y1+y2)/2;

return {x:x, y:y};
}
function getD(ev){
var x1=ev.targetTouches[0].pageX;
var y1=ev.targetTouches[0].pageY;

var x2=ev.targetTouches[1].pageX;
var y2=ev.targetTouches[1].pageY;

var x=x2-x1;
var y=y1-y2;

return a2d(Math.atan2(y,x));
}
function getS(ev){
var x1=ev.targetTouches[0].pageX;
var y1=ev.targetTouches[0].pageY;

var x2=ev.targetTouches[1].pageX;
var y2=ev.targetTouches[1].pageY;

var a=x1-x2;
var b=y1-y2;
return Math.sqrt(a*a+b*b);
}

 

if(ev.targetTouches.length==2){
var downX=getT(ev).x;
var downY=getT(ev).y;
var downD=getD(ev);
var downS=getS(ev);
}

document.addEventListener(‘touchmove‘,function(ev){
if(ev.targetTouches.length==2){
x=oldX+getT(ev).x-downX;
y=oldY+getT(ev).y-downY;
d=oldD+downD-getD(ev);
s=oldS*getS(ev)/downS;

oDiv.style.WebkitTransform=‘translate(‘+x+‘px,‘+y+‘px) scale(‘+s+‘) rotate(‘+d+‘deg)‘;
}
},false);

ev.preventDefault();
},false);
},false);
</script>
</head>
<body>
<div id="div1">DIV</div>
</body>
</html>

 

以上是关于UnityPC端:缩放移动画面的主要内容,如果未能解决你的问题,请参考以下文章

Unity 中的移动世界规模?

Unity3DUnity 游戏画面帧更新 ( 游戏物体 GameObject 移动 | 借助 Time.deltaTime 进行匀速运动 )

unity安卓开发尺寸

Unity Rigidbody2D 手册

Unity3D游戏物体操作 ( 场景简介 | 添加游戏物体 | 操作游戏物体 | 选中游戏物体 | 场景显示效果缩放 | 重命名游戏物体 | 复制游戏物体 | 删除游戏物体 | 移动游戏物体 )

Unity PC (Windows) 构建失败