unity2017官方已经支持了瓷砖,但我自己也写了个简单的自动瓷砖,权当学习,效果如图。

image

主要实现了两个功能:

① 根据周围格子的状态改变自己的状态

② 对2D物理碰撞体进行自动合并,优化性能

基本思路是遍历特定范围中的每个GameObjec,然后计算坐标,再通过坐标来处理瓷砖间的相对关系。先看基类,主要处理变换坐标的工作:

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

public class AutoTile : MonoBehaviour

{

/* 图块边长 */

public float sideLength;

/* 是否合并碰撞体 */

public bool isCoillder;

/* 左下角的起始块,标定开始计算的位置 */

public GameObject startOne;

/* 存储地图 */

List mapContainer = new List();

protected Transform[] childrenTransforms;

/* 存储子物体 */

protected Vector2 basePoint;

/* 从startone获取的起点 */

/* 初始化起点 */

protected void intinalBasePoint()

{

basePoint = startOne.transform.position;

/* Debug.Log ("BasePoint=" + basePoint); */

}

/* 初始化存储块信息的变长数组 */

protected void intinalMapContainer()

{

/* 获取子物体的数组 */

childrenTransforms = GetComponentsInChildren ( false );

foreach ( Transform tra in childrenTransforms )

{

/* 利用tag判断是否纳入计算 */

if ( tra.tag == "Tile" )

{

Vector2 pos = tra.position;

int x, y;

x = (int) ( (pos.x - basePoint.x) / sideLength + 0.05f);

/* 加0.05防止误差 */

y = (int) ( (pos.y - basePoint.y) / sideLength + 0.05f);

/* 判断是否延长主组 */

while ( mapContainer.Count <= x )

{

mapContainer.Add( new ArrayList() );

}

/* 向列数组填充元素 */

while ( mapContainer [x].Count <= y )

{

mapContainer [x].Add( 0 );

}

mapContainer [x][y] = 1;

}

}

return;

}

/* 以下has***函数是用来判断的工具函数,在子类中用到 */

protected bool hasUp( int x, int y )

{

if ( x < 0 || y < 0 )

return(false);

if ( !(mapContainer.Count > x) || mapContainer [x] == null )

return(false);

if ( mapContainer [x].Count == y + 1 )

return(false); else

return( ( (int) mapContainer [x] [y + 1]) == 1);

}

protected bool hasDown( int x, int y )

{

if ( x < 0 || y < 1 )

return(false);

if ( !(mapContainer.Count > x) || mapContainer [x] == null )

return(false);

return( (int) mapContainer [x] [y - 1] == 1);

}

protected bool hasLeft( int x, int y )

{

if ( x < 1 || y < 0 )

return(false);

if ( !(mapContainer.Count > x) )

return(false);

if ( mapContainer [x - 1] == null || mapContainer [x - 1].Count < y + 1 )

return(false);

return( (int) mapContainer [x - 1] [y] == 1);

}

protected bool hasRight( int x, int y )

{

if ( x < 0 || y < 0 )

return(false);

if ( !(mapContainer.Count > x + 1) )

return(false);

if ( mapContainer [x + 1] == null || mapContainer [x + 1].Count < y + 1 )

return(false);

return( (int) mapContainer [x + 1] [y] == 1);

}

protected bool hasLeftUp( int x, int y )

{

return(hasLeft( x, y + 1 ) );

}

protected bool hasRightUp( int x, int y )

{

return(hasRight( x, y + 1 ) );

}

protected bool hasLeftDown( int x, int y )

{

return(hasLeft( x, y - 1 ) );

}

protected bool hasRightDown( int x, int y )

{

return(hasRight( x, y - 1 ) );

}

/* 测试用 */

protected void test()

{

foreach ( ArrayList arraylist in mapContainer )

{

string output = null;

foreach ( var e in arraylist )

{

output += e;

}

Debug.Log( output );

}

}

public virtual void updateAllTile()

{

}

public virtual void updateAroundTile( int x, int y )

{

}

}

子类,用来更改Sprite与合并碰撞体,为什么要写子类呢?因为我觉得有拐角与没有的可以分开处理。

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

public class AutoEdgeTiles : AutoTile

{

/* 序列化不同的图片,也许有资源集之类更好的办法,还望大神能指点一二 */

public Sprite SpriteMid, SpriteLeft, SpriteRight, SpriteUp, SpriteDown,

SpriteUpLeft, SpriteUpRight, SpriteDownLeft, SpriteDownRight, SpriteUpDown, SpriteLeftRight,

SpriteOnlyOne, SpriteOnlyLeft, SpriteOnlyRight, SpriteOnlyUp, SpriteOnlyDown;

void Awake()

{

intinalBasePoint();

updateAllTile();

/*

* 测试用,testX,testY要声明

* test ();

* Debug.Log(hasLeftUp(testX, testY)+"t"+hasUp (testX, testY)+"t"+hasRightUp(testX, testY)+

* "n"+hasLeft(testX, testY)+"tt"+hasRight(testX, testY)+

* "n"+hasLeftDown(testX, testY)+"t"+hasDown(testX, testY)+"t"+hasRightDown(testX, testY));

*/

}

override public void updateAllTile()

{

/* 父类中 */

intinalMapContainer();

/* 遍历每个tile */

foreach ( Transform tra in childrenTransforms )

{

if ( tra.tag == "Tile" )

{

Vector2 pos = tra.position;

int x, y, code = 0;

x = (int) ( (pos.x - basePoint.x) / sideLength + 0.05f);

y = (int) ( (pos.y - basePoint.y) / sideLength + 0.05f);

if ( isCoillder )

changeCoillder2D( tra, x, y );

/*一种类似二进制的判别法

*顺序上左下右

*/

if ( hasUp( x, y ) )

code += 1;

if ( hasDown( x, y ) )

code += 4;

if ( hasLeft( x, y ) )

code += 8;

if ( hasRight( x, y ) )

code += 2;

tra.gameObject.GetComponent ().sprite = findSpriteWithCode( code, tra, x, y );

}

}

}

/* 在可破化地形情况下使用(没写) */

override public void updateAroundTile( int x, int y )

{

}

/* 改变角 */

void changeConer( Transform tra, int x, int y )

{

if ( !hasLeftUp( x, y ) && hasLeft( x, y ) && hasUp( x, y ) )

tra.Find( "conerLeftUp" ).gameObject.SetActive( true );

if ( !hasRightUp( x, y ) && hasRight( x, y ) && hasUp( x, y ) )

tra.Find( "conerRightUp" ).gameObject.SetActive( true );

if ( !hasRightDown( x, y ) && hasRight( x, y ) && hasDown( x, y ) )

tra.Find( "conerRightDown" ).gameObject.SetActive( true );

if ( !hasLeftDown( x, y ) && hasLeft( x, y ) && hasDown( x, y ) )

tra.Find( "conerLeftDown" ).gameObject.SetActive( true );

}

/* 假如是可碰撞体,就想办法合并Collider2D,节省性能并防止“抽搐”问题 */

void changeCoillder2D( Transform tra, int x, int y )

{

if ( hasUp( x, y ) && hasDown( x, y ) && hasLeft( x, y ) && hasRight( x, y ) )

{

tra.GetComponent ().enabled = false;

return;

} else if ( hasLeft( x, y ) )

{

tra.GetComponent ().enabled = false;

return;

} else if ( !hasLeft( x, y ) )

{

BoxCollider2D theBox = tra.GetComponent ();

int count = 1;

while ( hasRight( x + count - 1, y ) )

{

count++;

}

theBox.size = new Vector2( sideLength * count, sideLength );

theBox.offset = new Vector2( sideLength / 2.0f * (count - 1), 0 );

}

return;

}

Sprite findSpriteWithCode( int code, Transform tra, int x, int y )

{

switch ( code )

{

case 0:

return(SpriteOnlyOne);

case 1:

return(SpriteOnlyUp);

case 2:

return(SpriteOnlyRight);

case 3:

changeConer( tra, x, y );

return(SpriteDownLeft);

case 4:

return(SpriteOnlyDown);

case 5:

return(SpriteUpDown);

case 6:

changeConer( tra, x, y );

return(SpriteUpLeft);

case 7:

changeConer( tra, x, y );

return(SpriteLeft);

case 8:

return(SpriteOnlyLeft);

case 9:

changeConer( tra, x, y );

return(SpriteDownRight);

case 10:

return(SpriteLeftRight);

case 11:

changeConer( tra, x, y );

return(SpriteDown);

case 12:

changeConer( tra, x, y );

return(SpriteUpRight);

case 13:

changeConer( tra, x, y );

return(SpriteRight);

case 14:

changeConer( tra, x, y );

return(SpriteUp);

case 15:

changeConer( tra, x, y );

return(SpriteMid);

default:

changeConer( tra, x, y );

return(SpriteMid);

}

}

}

unity 陶瓷质感_Unity2D:简单自动瓷砖(Tile)的实现相关推荐

  1. unity 陶瓷质感_一种基于Unity3D的虚拟陶瓷设计方法与流程

    本发明涉及虚拟现实领域,特别涉及一种基于Unity3D的虚拟陶瓷设计方法. 背景技术: 陶艺工艺制作环境要求严格:不仅在拉坯成型需要利用旋转机器,在烧制过程则需要窑炉锻造,如何将陶瓷制作工艺与虚拟现实 ...

  2. Unity 工具 之 VText 简单快速实现 文字 3D 效果,VText 的导入设置和简单使用(可支持中文字体)

    Unity 工具 之 VText 简单快速实现 文字 3D 效果,VText 的导入设置和简单使用(可支持中文字体) 目录 Unity 工具 之 VText 简单快速实现 文字 3D 效果,VText ...

  3. 编译原理(简单自动词法分析器LEX)

    编译原理(简单自动词法分析器LEX)源程序下载地址:  http://files.cnblogs.com/files/hujunzheng/%E6%B1%87%E7%BC%96%E5%8E%9F%E7 ...

  4. Unity 进阶 之 实现简单的音频可视化封装(包括音频和麦克风)

    Unity 进阶 之 实现简单的音频可视化封装(包括音频和麦克 目录 Unity 进阶 之 实现简单的音频可视化封装(包括音频和麦克 一.简单介绍 二.实现原理 三.注意事项 四.效果预览 五.实现步 ...

  5. Ruby‘s Adventrue游戏制作笔记(十二)Unity给角色添加简单的特效

    Ruby's Adventrue游戏制作笔记(十二)Unity给角色添加简单的特效 前言 一.把特效物品进行切割 二.创建 particle System 三.创建彩色球 四.再设置一下其他属性 五. ...

  6. Vue 之 vue-seamless-scroll 实现简单自动无缝滚动,且添加对应点击事件的简单整理

    Vue 之 vue-seamless-scroll 实现简单自动无缝滚动,且添加对应点击事件的简单整理 目录 Vue 之 vue-seamless-scroll 实现简单自动无缝滚动,且添加对应点击事 ...

  7. Unity入门——实现一个简单的跑酷游戏(资源预制)

    Unity入门--实现一个简单的跑酷游戏 资源预制 一款跑酷游戏,需要大量重复的场景资源,比如道路.障碍物等,无论是从游戏体验的角度还是运行效率的角度考虑,都不应该全部事先摆好,而是应该由代码随机生成 ...

  8. 【Unity3D 灵巧小知识点】 ☀️ | Unity中几个简单又常见的报错异常

    Unity 小科普 老规矩,先介绍一下 Unity 的科普小知识: Unity是 实时3D互动内容创作和运营平台 . 包括游戏开发.美术.建筑.汽车设计.影视在内的所有创作者,借助 Unity 将创意 ...

  9. [Unity3D]用C#在unity里面写一个简单的红绿灯

    [Unity3D]用C#在unity里面写一个简单的红绿灯 00.成果展示 01.创建可变颜色的小球 02.编写代码 R1.cs R2.cs G1.cs G2.cs Y1.cs Y2.cs 03.自己 ...

最新文章

  1. IDEA IntelliJ 如何给web项目配置tomcat
  2. 设计模式C++实现(13)——中介者模式
  3. Longest Palindromic Substring
  4. spring boot jwt_springboot整合JWT
  5. 「新手向」koa2从起步到填坑
  6. JAVA常见算法题(四)
  7. 中缀表达式转后缀表达式(Java)
  8. 鸿蒙系统硬盘分区,硬盘分区2种格式
  9. 使用bat注册ocx
  10. 怎么用计算机测出来体脂,keep软件测体脂率的在哪 keep怎么测体脂
  11. ISAPI概述(转)
  12. 用一报还一报(TIT FOR TAT)策略的胜利指导我们的生活和人际交往
  13. “真功夫”与“花拳绣腿”
  14. 【中创算力】第六届优秀员工表彰大会暨四月中创生日会
  15. ps铅笔素描效果教程
  16. Hash——哈希法概念、哈希函数构造方法、哈希冲突解决办法(重点讨论链地址法)
  17. CTF MISC系列————8、Misc1-纵横四海
  18. CVS投中app数据采集
  19. Java分离中文姓名姓氏和名字
  20. php去除换行符的方法

热门文章

  1. 【VCS】Git之无尽探索
  2. 程序员为什么要英文好?
  3. 一个纸杯子的测试用例
  4. 五子棋联机对战(JAVA实现)含源码
  5. 为什么别人在微信卖东西不会被人拉黑
  6. 关于anchor的解释
  7. 克罗内克积(Kronecker product)与笛卡尔乘积(Cartesian product)
  8. Thinkphp5 php会员实现单点登录
  9. 产品经理--无人岛的项目开发与推广
  10. vue向后端发送数据并得到返回值