Unity中material.mainTextureOffset和material.mainTextureScale的作用和用法

mainTextureOffset和mainTextureScale是Material类中的两个方法

mainTextureOffset指的是主纹理偏移

mainTextureScale指的是主纹理缩放

默认一个material的mainTextureOffset是0,0,mainTextureScale是1,1

表示原图正常显示,没有缩放,如下图

当我们改变mainTextureScale的值时纹理只会显示一部分,其范围是[0,1];

如我们将mainTextureScale.x设置为0.5时,可以看到纹理只显示u方向的50%

同理,我们将mainTextureScale.y设置为0.5时,可以看到纹理只显示v方向的50%

mainTextureOffset属性表示纹理的起始偏移,为0时没有偏移,mainTextureOffset.x指u方向的偏移量,mainTextureOffset.y指v方向的偏移量。其范围也是[0,1]。这里要注意:偏移的起点在图像的左下角

我们设置mainTextureOffset.x为0.2,如下图:

可以看到纹理向左偏移了20%

我们设置mainTextureOffset.y为0.2,如下图:

可以看到纹理向下偏移了20%

应用这两个属性,我们可以只截取图片的一部分来显示,如:

mainTextureOffset = new Vector2(0.5, 0.5);

mainTextureScale= new Vector2(0.5, 0.5);

将只显示原图的右上角1/4区域,如下图:

有了对以上两个属性的了解,我们可以来制作一个简单的拼图游戏

思路:

1.将一张图片切分为raw*volumn的raw*volumn张碎片

2.每一张碎片只显示图片的一部分

3.将它们按一个顺序和位置排列,使其看起来像一张完整的图片

玩法:

点击Start按钮后,开始游戏。选中碎片并将其拖放在正确的位置上,如放置正确则不可再被拖动。直到所有碎片放置正确。

点击Next Texture按钮可切换背景和碎片显示的图片

制作流程:

新建一个游戏场景Test,设置摄像机属性如下(采用正交摄像机(2D)将其标签设置MainCamera):

创建两个plane,其中一个改名为Background并为其选择一个材质;另一个plane也选择一个材质要和前一个不同,选择shader为Unlit/Transparent (自发光),将其设为不可见。创建一个空对象,起名为Body,如下图:

创建一个c#脚本main.cs,绑定在Body对象下。Inspector设置如下:

main.cs脚本如下:

using UnityEngine;
using System.Collections;

public class main : MonoBehaviour {

public GameObject _plane;        //用来实例碎片的对象
    public GameObject _planeParent; //碎片对象所要绑定的父节点
    public GameObject _background;    //显示暗色的背景图
    public Texture2D[] _texAll;        //用来更换的纹理
    public Vector3[] _RandomPos;    //开始时, 碎片随机分布的位置
    public int raw = 3;                //图形切分的行数
    public int volumn = 3;            //图形切分的列数
    public float factor = 0.25f;    //一个范围比例因子, 用来判断碎片是否在正确位置范围内
    
    GameObject[] _tempPlaneAll;        
    
    float sideLength = 0;            //背景图的边长(正方形)
    
    int finishCount = 0;            //完成的碎片数量
    int _index = 0;
    
    Vector2 originPoint;            //第一个碎片的位置
    Vector2 space;                    //碎片与碎片之间的间隔(中心距x,y)
    
    void Start()
    {
        sideLength = _background.transform.localScale.x;
        space.x = sideLength / volumn;
        space.y = sideLength / raw;
        originPoint.x = -((volumn - 1) * space.x) / 2;
        originPoint.y = ((raw - 1) * space.y) / 2;
        Vector2 range;
        range.x = space.x * factor * 10f;
        range.y = space.y * factor * 10f;
        
        _tempPlaneAll = new GameObject[raw * volumn];
        int k = 0;
        //完成所有碎片的有序排列位置和uv纹理的截取
        for(int i = 0 ; i != raw ; ++i)
        {
            for(int j = 0 ; j != volumn ; ++j)
            {
                GameObject tempObj = (GameObject)Instantiate(_plane);
                tempObj.name = "Item" + k;
                tempObj.transform.parent = _planeParent.transform;
                tempObj.transform.localPosition = new Vector3((originPoint.x + space.x * j) * 10f, (originPoint.y - space.y * i) * 10f, 0);
                tempObj.transform.localScale = new Vector3(space.x, 1f, space.y);
                Vector2 tempPos = new Vector2(originPoint.x + space.x * j, originPoint.y - space.y * i);
                
                float offset_x = (tempPos.x <= 0 + Mathf.Epsilon) ? (0.5f - Mathf.Abs((tempPos.x - space.x / 2) / sideLength)) : (0.5f + (tempPos.x - space.x / 2) / sideLength);
                float offset_y = (tempPos.y <= 0 + Mathf.Epsilon) ? (0.5f - Mathf.Abs((tempPos.y - space.y / 2) / sideLength)) : (0.5f + (tempPos.y - space.y / 2) / sideLength);
                
                float scale_x = Mathf.Abs(space.x / sideLength);
                float scale_y = Mathf.Abs(space.y / sideLength);
                
                tempObj.renderer.material.mainTextureOffset = new Vector2(offset_x, offset_y);
                tempObj.renderer.material.mainTextureScale = new Vector2(scale_x, scale_y);
                tempObj.SendMessage("SetRange", range);
                
                _tempPlaneAll[k] = tempObj;
                ++k;
            }
        }
    }
    
    void OnGUI()
    {
        //开始游戏
        if(GUI.Button(new Rect(10, 10, 100, 30), "Play"))
            StartGame();
        //更换纹理
        if(GUI.Button(new Rect(10, 80, 100, 30), "Next Textrue"))
            ChangeTex();
    }
    
    void StartGame()
    {
        //将所有碎片随机分布在左右两边
        for(int i = 0 ; i != _tempPlaneAll.Length ; ++i)
        {
            int tempRank = Random.Range(0, _RandomPos.Length);
            _tempPlaneAll[i].transform.localPosition = new Vector3(_RandomPos[tempRank].x, _RandomPos[tempRank].y, 0f);
        }
        //通知所有子对象, 开始游戏
        gameObject.BroadcastMessage("Play");
    }
    
    void SetIsMoveFale()
    {
        gameObject.BroadcastMessage("IsMoveFalse");
    }
    
    void IsFinish()
    {
        //计算放置正确的碎片数量
        ++finishCount;
        if(finishCount == raw * volumn)
            Debug.Log("Finish!");
    }
    
    void ChangeTex()
    {
        _background.renderer.material.mainTexture = _texAll[_index];
        gameObject.BroadcastMessage("SetTexture", _texAll[_index++]);
        if(_index > _texAll.Length - 1)
            _index = 0;
    }
    
}

再创建一个c#脚本为plane.cs,绑定在Plane对象下。Inspector设置如下:

注意:要为Plane对象添加一个Collider组件,因为Plane对象的scale与Unity的基本单位(米)的比例为10:1,因此这里Collider的Size要设置为10

plane.cs脚本如下:

using UnityEngine;
using System.Collections;

public class plane : MonoBehaviour {
    
    Transform mTransform;
    
    Vector3 offsetPos;                    //鼠标点与所选位置的偏移
    Vector3 finishPos = Vector3.zero;    //当前碎片的正确位置
    
    Vector2 range;                        //碎片正确位置的范围, 由SetRange函数设置
    
    float z = 0;
    
    bool isPlay = false;                //是否进行游戏?
    bool isMove = false;                //当前碎片是否跟随鼠标移动
    
    void Start()
    {
        mTransform = transform;
        finishPos = mTransform.localPosition;
    }
    
    void Update()
    {
        if(!isPlay)
            return ;
        
        //当鼠标进入碎片中按下时, 记录与碎片中心位置的偏差; 并使碎片跟随鼠标移动(多张碎片叠在一起时,只选其中一张跟随)
        Vector3 tempMousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
        if(Input.GetMouseButtonDown(0) && tempMousePos.x > collider.bounds.min.x && tempMousePos.x < collider.bounds.max.x
            && tempMousePos.y > collider.bounds.min.y && tempMousePos.y < collider.bounds.max.y)
        {
            mTransform.parent.SendMessage("SetIsMoveFale");
            offsetPos = mTransform.position - tempMousePos;
            z = mTransform.position.z;
            isMove = true;
        }
        
        //跟随鼠标移动
        if(isMove && Input.GetMouseButton(0))
        {
            tempMousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            mTransform.position = new Vector3(tempMousePos.x + offsetPos.x, tempMousePos.y + offsetPos.y, z - 0.1f);
        }
        
        //鼠标放开后停止跟随
        if(Input.GetMouseButtonUp(0))
        {
            mTransform.position = new Vector3(mTransform.position.x, mTransform.position.y, z);
            isMove = false;
        }
        
        //判断是否到达正确位置(如进入正确位置范围, 碎片自动设置在正确位置, 并不可被再移动)
        IsFinish();
    }
    
    void IsFinish()
    {
        if(mTransform.localPosition.x > finishPos.x - range.x && mTransform.localPosition.x < finishPos.x + range.x
            && mTransform.localPosition.y > finishPos.y - range.y && mTransform.localPosition.y < finishPos.y + range.y)
        {
            isPlay = false;
            mTransform.localPosition = finishPos;
            mTransform.parent.SendMessage("IsFinish");
        }
    }
    
    //开始游戏
    void Play()
    {
        isPlay = true;
    }
    
    void IsMoveFalse()
    {
        isMove = false;
    }
    
    void SetRange(Vector2 _range)
    {
        range = _range;
    }
    
    //更换纹理
    void SetTexture(Texture2D _tex)
    {
        mTransform.renderer.material.mainTexture = _tex;
    }
}

现在可以开始游戏了,如下图:

程序源码及打包文件在此下载:http://download.csdn.net/detail/cube454517408/4525682

使用方法:打开一个空Unity场景,点击Assets->Import Package->Custom Package导入即可。注意:不要有中文路径

unity 制作拼图游戏相关推荐

  1. C#利用控件拖拽技术制作拼图游戏

    C#利用控件拖拽技术制作拼图游戏 这篇文章主要介绍了C#利用控件拖拽技术制作拼图游戏的方法以及核心代码,需要的朋友可以参考下 主要实现的功能: 1.程序附带多张拼图随机拼图. 2.可手动添加拼图. 3 ...

  2. Unity制作格斗游戏核心思路总结

    http://anchorart9.com/2016/05/22/unity%E5%88%B6%E4%BD%9C%E6%A0%BC%E6%96%97%E6%B8%B8%E6%88%8F%E6%A0%B ...

  3. cs6制作拼图游戏 dreamweaver_教你做简单的拼图游戏[图、实例]

    其实照着教程做起了很简单,就是代码要研究明白了需要废点时间,我把我学的那个教程copy了一遍,大家都来做做看,真得不难! --------------------------------------- ...

  4. cs6制作拼图游戏 dreamweaver_Dreamweaver拼图游戏的实现

    龙源期刊网 http://www.qikan.com.cn Dreamweaver 拼图游戏的实现 作者:罗月红 来源:<读与写 · 教育教学版> 2015 年第 08 期 摘要:随着计算 ...

  5. cs6制作拼图游戏 dreamweaver_DIY硬纸板拼图华容道游戏盘

    家里给小孩子买过大大小小的拼图,同一个图案的拼图玩的多了小孩子的兴趣也就没有了.而且,买来的拼图都有同样的问题:容易散落,容易缺失.怎么样保持小孩子对拼图的兴趣,当然是要不停地让他可以有新的图案可以玩 ...

  6. unity制作小游戏

    前言 这是专选课3D游戏编程与设计的第二次作业,包括简答题和用unity制作一个小游戏.如有错误,欢迎并感谢指正. 简答题 游戏对象(GameObjects)和资源(Assets)的区别和联系 游戏对 ...

  7. html5制作拼图游戏教程,用HTML5制作视频拼图的教程

    几天前同事给我看了一个特效,是一个拼图游戏,不同的是,拼图里的是动画.他让我看下做个DEMO,于是就自己整了一会,也确实不难.用canvas很容易做.所以这篇博文不适合高手看....就是随便写来玩玩的 ...

  8. cs6制作拼图游戏 dreamweaver_Dreamweaver制作拼图步骤

    1 .处理图片 ①打开 Photoshop 软件 ②打开图片 kdc.jpg ,选择切片工具. ③对图片进行"划分切片" ,水平划分为 2 ,垂直划分为 2 . ④保存为" ...

  9. linux编程拼图游戏,cocos2d-x制作拼图游戏

    由于本人最近在学习cocos2d-x,一时手痒,写一个游戏练练手,也是对cocos2d-x进一步的巩固,于是敲了两天,就写了这个拼图游戏,还挺有成就感的,:-),先把我的成果展示如下: 由于cocos ...

最新文章

  1. 服务端如何识别是selenium在访问以及解决方案参考二
  2. 改变按钮在iPhone下的默认风格
  3. 技术讨论 | 一次尚未完成的薅羊毛行动
  4. linq to sql 多条件组合查询
  5. [渝粤教育] 广东-国家-开放大学 21秋期末考试建筑工程概预算10326k2
  6. 13.Azure流量管理器(上)
  7. OpenCV手部关键点检测(手势识别)代码示例
  8. C#、TypeScript之父Anders Hejlsberg:“会用Excel就是程序员 ”
  9. 使用Nacos配置中心云端化本地application.properties
  10. 同步,异步,阻塞,非阻塞?
  11. Spring Bean生命周期总结
  12. Matlab绘制直方图、概率密度函数、累积分布函数
  13. MatLab数字图像处理实战(赵小川)-sift原理
  14. excel中快速输入打勾
  15. 各类邮箱POP3和SMTP服务器地址和端口
  16. 计算机与电视如何通过网络连接,怎么设置电脑和电视共用一根网线上网
  17. 【Rust日报】2022-07-20 极简主义 Poem 指南
  18. 初识 CGI,CGI 简识
  19. php实现邮箱激活功能
  20. 开放英语计算机考试,(荐)最新电大《英语I(1)》(开放英语1)完成句子、翻译题归纳汇总复习小抄.doc...

热门文章

  1. 【六月英语——空空的】
  2. [SPOJ IGAME Interesting Game]Nim 博弈+数位DP
  3. 表格数据横向转纵向并在el-table中渲染
  4. Python Django 基本创建 App创建
  5. oracle如何在月份前面加0,时间怎么把月份数字前面添加0
  6. matlab 语音识别为文字,语音识别(Speech Recognition)是让机器通过识别和理解过程把语音信号转变为相应的文本...
  7. 【笔记整理】面试笔记
  8. 如何在jieba分词中加自定义词典_中文到底需要分词嘛?
  9. 免费公共DNS的IP地址
  10. 算法证明题 8.9 HITTING SET