Unity Image(RawImage) 实现按轴心放大缩小,序列化存储轴心信息,实现编译器窗口保存轴心

这篇具有很好参考价值的文章主要介绍了Unity Image(RawImage) 实现按轴心放大缩小,序列化存储轴心信息,实现编译器窗口保存轴心。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

工作时分配给我的要实现的功能,写的时候遇到挺多的坑的,在此记录一下

效果

放大缩小的效果
Unity Image(RawImage) 实现按轴心放大缩小,序列化存储轴心信息,实现编译器窗口保存轴心,unity,游戏引擎

2.编译器扩展窗口记录Unity Image(RawImage) 实现按轴心放大缩小,序列化存储轴心信息,实现编译器窗口保存轴心,unity,游戏引擎

实现点

1.Json序列化存储图片轴心位置, 放大倍率,放大所需要的事件
2.用了编译器扩展工具便于保存轴心信息

坑点

1.Image和RawImage的坐标都是以轴心位置计算的,更改轴心就需要重定位
2.确保画布的分辨率和测试的屏幕分辨率一致
3.计算轴心偏移和别忘记在乘以自己的放大倍率

工具的使用

1.打开WSC/保存图片轴心工具,在Image位置挂在需要保存轴心的图像,输出name作为key,并在Scene窗口中直接拖动轴心确定位置(不建议在Inspector中手动输入轴心修改,这样会让图像重定位)
Unity Image(RawImage) 实现按轴心放大缩小,序列化存储轴心信息,实现编译器窗口保存轴心,unity,游戏引擎
Unity Image(RawImage) 实现按轴心放大缩小,序列化存储轴心信息,实现编译器窗口保存轴心,unity,游戏引擎

2.程序调用

无论是简化key传入还是传入轴心对象的方式都需要传入要放大的Image

Unity Image(RawImage) 实现按轴心放大缩小,序列化存储轴心信息,实现编译器窗口保存轴心,unity,游戏引擎

Unity Image(RawImage) 实现按轴心放大缩小,序列化存储轴心信息,实现编译器窗口保存轴心,unity,游戏引擎文章来源地址https://www.toymoban.com/news/detail-625116.html

代码

using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.UI;
using DG.Tweening;

namespace YBZ
{
    public class ControlImage : MonoBehaviour
    {   
        
        // 需要控制的图片
        [Header("2D的图像,如果是视屏改为RawImage进行推流即可")]
        public Image image;

        // Start is called before the first frame update
        void Start()
        {   
            if(image == null){
                
                if(!TryGetComponent<Image>(out image)){
                    gameObject.AddComponent<Image>();
                    image = GetComponent<Image>();
                }
            }
            rect = image.GetComponent<RectTransform>();

            // 先读取json中的文件
            Utility.Instance.ReadData();

            StartCoroutine(five());

        }

        IEnumerator five(){
            Utility.Instance.ImageZoom(image, Utility.Instance.dict["1"]);
            yield return new WaitForSeconds(1);

            Utility.Instance.ImageZoom(image, Utility.Instance.dict["2"]);
            yield return new WaitForSeconds(1.01f);

            Utility.Instance.ImageZoom(image, Utility.Instance.dict["3"]);
            yield return new WaitForSeconds(1.01f);
            
            Utility.Instance.ImageZoom(image, Utility.Instance.dict["4"]);
            yield return new WaitForSeconds(1.01f);
            
            Utility.Instance.ImageZoom(image, Utility.Instance.dict["5"]);
            yield return new WaitForSeconds(3.01f);

            Utility.Instance.ImageZoom(image, Utility.Instance.dict["6"]);
            yield return new WaitForSeconds(1.01f);

            Utility.Instance.ImageZoom(image, Utility.Instance.dict["7"]);
            yield return new WaitForSeconds(1.51f);

            Utility.Instance.ImageZoom(image, Utility.Instance.dict["8"]);
            yield return new WaitForSeconds(1.51f);

            Utility.Instance.ImageZoom(image, Utility.Instance.dict["9"]);
            yield return new WaitForSeconds(2.01f);

            Utility.Instance.ImageZoom(image, Utility.Instance.dict["10"]);
            yield return new WaitForSeconds(2.01f);

            Utility.Instance.ImageZoom(image, Utility.Instance.dict["11"]);
            yield return new WaitForSeconds(2.01f);

            Utility.Instance.ImageZoom(image, Utility.Instance.dict["12"]);
            yield return new WaitForSeconds(2.01f);

            Utility.Instance.ImageZoom(image, Utility.Instance.dict["RESET"]);
        }

        // 图片的放大接口
        public void ZoomEvent(Image image, string key){
            Utility.Instance.ZoomPivot(image, key);
        }

        
    }


    // 单例模式
    // 命名冲突时,请指定命名空间
    // 使用前一定要读取数据!
    public class Utility{

        public static Utility instance;

        public static Utility Instance { 
            get{
                if(instance == null) instance = new Utility();
                return instance;
            }
        }



        // 放大点位置的字典
        public Dictionary<String, ZoomPoint> dict = new Dictionary<string, ZoomPoint>();
        
        //json文件的位置,这个位置默认是在SteamingAssets下的
        private string jsonFileName ="/2DPivots.json";

        private string filePath =""; // "StreamingAssets/2Dpivots"
        public void SetFilePath(string value) => filePath = value;

        // 写入数据
        public void WriteDataTest(){
            Data data = new Data();
            data.zoomPoints = new List<ZoomPoint>();

            ZoomPoint point1 = new ZoomPoint
            {
                name = "1",
                pivot = new Vector2(0.75f,0.75f)
            };
            ZoomPoint point2 = new ZoomPoint
            {
                name = "2",
                pivot = new Vector2(0.5f,0.5f)
                
            };

            data.zoomPoints[0] = point1;
            data.zoomPoints[1] = point2;

            string js = JsonUtility.ToJson(data);

            // 获取项目路径
            string fileUrl;
            if(filePath == ""){
                fileUrl = Application.streamingAssetsPath + jsonFileName;
            }else{
                fileUrl = filePath;
            }
            
            using(StreamWriter sw  = new StreamWriter(fileUrl))
            {   
                sw.WriteLine(js); //保存数据
                sw.Close(); 
                sw.Dispose();
            }
        }  


        public void WriteData(ZoomPoint zp){
            Data data = ReadData();
            
            if(data != null && data.zoomPoints != null){
                foreach(var temp in data.zoomPoints){
                    if(temp.name == zp.name){
                        Debug.LogError("轴心名字重复 !(⊙_⊙)?");
                        return;
                    }
                }
            }
            
            data.zoomPoints.Add(zp);

            string js = JsonUtility.ToJson(data);

            // 获取项目路径
            string fileUrl;
            if(filePath == ""){
                fileUrl = Application.streamingAssetsPath + jsonFileName;
            }else{
                fileUrl = filePath;
            }

            using(StreamWriter sw  = new StreamWriter(fileUrl))
            {   
                sw.WriteLine(js); //保存数据
                sw.Close(); // 关闭文档
                sw.Dispose();
            }
            Debug.Log("保存成功(*^▽^*)");
        }

        /// <summary>
        /// 读取数据,在外界不需要接受Data只需要调用即可,返回的Data仅供我自己编写其他程序耦合使用,忽略返回值
        /// 请在调用dict 前一定要先调用ReadData函数
        /// </summary>
        public Data ReadData(){
            // 获取项目路径
            string fileUrl;
            if(filePath == ""){
                fileUrl = Application.streamingAssetsPath + jsonFileName;
            }else{
                fileUrl = filePath;
            }
            
            //读取文件
            string readDate;
            using (StreamReader sr = File.OpenText(fileUrl)){
                readDate = sr.ReadLine();
                sr.Close();
            }

            Data data = JsonUtility.FromJson<Data>(readDate);

            // 分配内存
            if(data == null ){
                data = new Data();
                data.zoomPoints = new List<ZoomPoint>();
                return data;
            }

            // 数据保存到字典里
            foreach(ZoomPoint zp  in data.zoomPoints){
                dict.TryAdd(zp.name, zp);
            }
            return data;
        }

        /// <summary>
        /// 按点放大轴心,无法捕获动画一定确保放大的动画之间不会冲突,简化了ImageZoom的调用
        /// </summary>
        /// <param name="zoomObj">被放大图像</param>
        /// <param name="key">轴心的名字</param>
        public void ZoomPivot(Image zoomObj, string key){
            ImageZoom(zoomObj, dict[key]);
        }

        /// <summary>
        /// 按倍率,轴心定位的方法放大图形,如果目标的轴心不在中心,会在设定完轴心后将目标移动到轴心,
        /// 需要注意的事,图片的坐标位置是以轴心位置为确定的,也因此放大缩小不改变图像的世界坐标
        /// </summary>
        /// <param name="zoomObj">需要方法的图像</param>
        /// <param name="x">轴心的x</param>
        /// <param name="y">轴心的y</param>
        /// <param name="zoomMagnification">放大倍率</param>
        /// 
        public void ImageZoom(Image zoomObj , ZoomPoint zp){
            float x = zp.pivot.x;
            float y = zp.pivot.y;
            float zoomMagnification = zp.zoomMagnification;
            float time = zp.time;

            // 当前和目标按图轴心位置 
            Vector3 currentPivotPostition = new Vector3(zoomObj.rectTransform.rect.width * zoomObj.rectTransform.pivot.x, zoomObj.rectTransform.rect.height * zoomObj.rectTransform.pivot.y) * zoomMagnification;
            Vector3 targetPivotPosition = new Vector3(zoomObj.rectTransform.rect.width * x, zoomObj.rectTransform.rect.height * y) * zoomMagnification;

            zoomObj.rectTransform.pivot = new Vector2(x, y); // 设定轴心
            zoomObj.transform.position += targetPivotPosition - currentPivotPostition; // 重定位

            Vector3 targetPostion = zoomObj.transform.position + currentPivotPostition - targetPivotPosition;

            //位移
            Translate(zoomObj, targetPostion, time);

            // 2023.7.30 经过测试,缩放仍然是更具初始轴心,能够达到理想效果不需要将LocalScale恢复为1
            // 为了结算范围失控的问题,需要将localScale恢复为1,再放大为需要的大小
            // zoomObj.rectTransform.localScale = new Vector3(1,1,1);
            Vector3 targetScale = new Vector3(zoomMagnification, zoomMagnification, zoomMagnification);
            zoomObj.rectTransform.DOScale(targetScale, time);

        }

        // 该方法主要是需要将目标点移动到坐标终点
        public void Translate(Image zoomObj, Vector3 target, float time){
            // 计算当前轴心和新轴心之间的位置
            Vector3 current = zoomObj.transform.position;
            // 移动
            zoomObj.transform.DOMove(target, time);
        }
    }
    

    // 数据存储接受类
    [Serializable]
    public class Data{
    	// 不能用字典直接存储,可以采用数据列表这样的连续空间
        // public ZoomPoint[] zoomPoints;
        // public Dictionary<string, ZoomPoint> zoomPoints;
        public List<ZoomPoint> zoomPoints;
    }


    // 可序列化
    [Serializable]
    public class ZoomPoint
    {
        // 点名称, 将作为Key被字典存储
        public string name;

        // 轴心X坐标
        public Vector2 pivot = Vector2.one / 2;

        // 放大倍率,小于1是为缩小倍率,小于0是取绝对值,不允许原点对称缩放,需要保证计算轴心逻辑正确
        // 默认设为1.5f 放大倍率
        public float zoomMagnification = 5f;

        // 改变的需要的时间,默认设为1f
        public float time = 1.0f;

        public override string ToString()
        {
            return $"name = {this.name}, pivot = ({pivot.ToString()}), zoomMagnification = {this.zoomMagnification}, time = {this.time}";
        }
    }

	
    // 实现编译器窗口扩展
    public class Editor :  ScriptableWizard 
    {
        //  文件路径
        public string filePath = Application.streamingAssetsPath + "/2DPivots.json";

        [SerializeField]
        public Image image;

        // 作为轴心点保存定位的Key
        new public string name;

        // 轴心
        public Vector2 pivot;

        // 放大倍率
        public float zoomMagnification = 5f;

        // 动画时间
        public float time = 1.0f;


        [MenuItem("WSC/保存图片轴心")]
        public static void CreateWizard() {
            ScriptableWizard.DisplayWizard<Editor>("Image zoom info save","退出", "保存当前轴心");
        }

        private int count = 1;
        void OnWizardCreate()
        {
            Utility.Instance.SetFilePath(filePath);
            Utility.Instance.ReadData();
            Debug.Log("轴心更新完毕(^-^)V");
        }

        void OnWizardOtherButton(){
            pivot = image.rectTransform.pivot;
            if (name == null) 
                name = (count++).ToString();

            ZoomPoint zp = new ZoomPoint
            {
                name = this.name,
                pivot = pivot,
                zoomMagnification = this.zoomMagnification,
                time = this.time
            };

            // reset image pivot
            Utility.Instance.WriteData(zp);
        }
    }
    

}


到了这里,关于Unity Image(RawImage) 实现按轴心放大缩小,序列化存储轴心信息,实现编译器窗口保存轴心的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • Unity打包窗口化放大、缩小、拖拽功能、无边框设置 C#

    Unity打包窗口化放大、缩小、拖拽功能、无边框设置 C#

    Unity无边框设置、窗口化放大、缩小、拖拽 提示:PC端打包,测试尽量在打包后测试。 编辑器下测试会有意想不到的后果呦~~ [DllImport(\\\"user32.dll\\\")] 。 代码如下: 代码如下:注释详细,不懂就问哈 代码整体已贴出,功能亲测可用,欢迎学习交流。点赞+收藏+关注哦~

    2024年02月16日
    浏览(14)
  • js实现图片的放大缩小(鼠标长按拖拽、鼠标滚轮控制放大缩小)

    js实现图片的放大缩小(鼠标长按拖拽、鼠标滚轮控制放大缩小)

    该功能的需求点事2个月前的一个需求,当时采用的是Element-UI中的image图片做的一个功能,但是不能满足产品真实的需求,只能定制化自己封装。 该功能在Vue2 的element-UI中还是比较鸡肋的 ⬇️ ⬇️ Element-UI 该功能在Emenent-UI-plus(vue3)版本已经很好的支持了。 完整功能如下

    2024年02月03日
    浏览(44)
  • unity 通过 二维数组序列化 实现二维数组在编辑器面板查看和配置数据

    unity 通过 二维数组序列化 实现二维数组在编辑器面板查看和配置数据

    实现思路如下: 1、定义一个二维数组数据类 2、奖数据类标记为 Serializable  并实现 unity内置的  ISerializationCallbackReceiver接口,接口提供了序列化和反序列化方法,参见官方文档(文档中给出了字典的序列化方法):Unity - Scripting API: ISerializationCallbackReceiver 3、使用unity序列化

    2024年02月08日
    浏览(39)
  • 前端Vue3+TS实现视频放大缩小,放大后实现视频的拖动+拖动边框限制

    最近实现了一个新的需求,大体内容是要对所播放的视频做一个放大缩小的处理,同时在视频放大的同时要实现视频的一个拖拽,拖拽的同时,要对视频拖动的范围作出一个限制,下面来看看我的一个实现的思路。 技术栈:Vue3.2 + TS 1.放大缩小采用的形式是什么? 2.拖动实现

    2024年01月25日
    浏览(16)
  • Vue 实现图片监听鼠标滑轮滚动实现图片缩小放大功能

    Vue 实现图片监听鼠标滑轮滚动实现图片缩小放大功能

    前言 其实想要实现功能很简单,就是在一张图片上监听鼠标滑轮滚动的事件,然后根据上滚还是下滚实现图片的缩放。 效果: 注:该配图使用《漫画|有趣的了解一下赋值、深浅拷贝》文章图片,不存在侵权问题。 实现思路 在js中,onmousewheel是鼠标滑轮滚动事件,可以通过

    2024年02月01日
    浏览(52)
  • LabVIEW鼠标滚轮实现波形放大缩小(zoom)功能

    LabVIEW鼠标滚轮实现波形放大缩小(zoom)功能

    实现功能:将鼠标放在波形图曲线上,滚轮可以实现波形放大缩小功能。 代码思想:注册鼠标滚轮事件,滚轮时改变波形图横纵坐标最大值和最小值。 鼠标滚轮 方式1:github链接 https://github.com/Gnepuil79/LabVIEW.git 方式2:百度网盘 链接:https://pan.baidu.com/s/1RUBZM8dy7jGIbimpze9cSA 提取

    2024年01月16日
    浏览(11)
  • CSS实现图片放大缩小的几种方法

    参考 常用使用img标签,制定width或者height的任意一个,图片会自动等比例缩小 但是不知道为什么我在uniapp小程序中这样写并没有等比缩小 使用CSS3新属性,transform的scale 大于1: 放大 小于1: 缩小 使用背景图设置图片 https://www.runoob.com/cssref/css3-pr-background.html

    2024年01月19日
    浏览(8)
  • vue实现 图片拖拽及鼠标滚轮放大缩小

    vue实现 图片拖拽及鼠标滚轮放大缩小

    效果: 代码实现

    2024年02月14日
    浏览(47)
  • openlayers实现锁定地图,不可使用鼠标拖动放大缩小地图

    openlayers实现锁定地图,不可使用鼠标拖动放大缩小地图

    开启地图锁定功能,不再允许使用鼠标拖拽查看地图,使用鼠标滚轮放大缩小查看地图 关键代码 包含业务开关的代码 注:这个图是别的大佬整理的 https://www.ktanx.com/blog/p/2656

    2024年02月02日
    浏览(18)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包