Paper Doll:2D换装游戏


GameObject.GetComponentsInChildren<>(可抽象为find()、*transform据说也一样 *:错了,可以找到只要transform组件没有关掉)不能找到active为fasle的物体
对于sprite(或image资源建立的游戏对象而言,如果靠gameObject.enable来控制显示和隐藏,enable=false后将无法再次获取并显示。想要控制其显示和隐藏,可以用这个方法来获取它的SpriteRenderer(或者image),然后再enabled=false掉,实现切换显示内容的功能

解决问题tips
一是一个方法不行,可以想想别的方法
比如gameobject控制显示不行换成spriterenderer
二是不熟悉api导致的入坑,所以要多看api?

找出问题tips
一、调试,思考坑出在哪一环节
二、抽象问题,如将GetComponentsInChildren<>抽象为获取、查找…(方便查到更多相关资料)

小坑
autolayout好像只有gridLayout需要子物体加上了elementLayout才能生效(后面发现又不需要了???莫名其妙)

坑之二
viewport的mask或者2Dmask貌似对sprite没有用,只对image有用,因为image是靠Canvas Renderer组件渲染,而sprite是靠Sprite Renderer组件在3D空间上渲染。因此sprite需要专门的spriteMask,并且并不是在viewport加上spriteMask就可以,还得靠新创建一个spriteMask才行(因为viewport本身使用Canvas Renderer渲染),还有哇,这个组件的sprite(mask)需要不透明的,如果透明则需要显示的内容sprite也会透明(猜测是由于需要将透明和不透明部分区分开来的缘故,如果透明的部分也可以作为mask的话会导致形状和不透明部分有出入)
配合灰度sprite(import setting-advanced-alpha source-from gray scale)

image的透明部分不会自动裁剪掉,所以给ta的点击事件加上代码如下(需要修改sprite资源为readable)
private void Start()
{
Image image = gameObject.GetComponent();
image.alphaHitTestMinimumThreshold = 0.5f;
}

此项目使用sprite是由于unity的sprite swap功能

坑之三
Unity中的2D射线检测(和3D的不一样呀)
private void Update()
{
if (Input.GetMouseButtonDown(0))
{
RaycastHit2D hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero);
if (hit.collider!=null)
{
_Tag = hit.collider.tag;
}
}
}
————————————————
原文链接:https://blog.csdn.net/weixin_44149074/article/details/96431559

中间弃坑了一段时间做别的游戏(LP)去了,因为使用了sprite作为scrollView的翻滚内容,虽然使用了spriteMask,让它在移出范围时能够隐藏,但是发现仍然能够在它隐藏的位置里触发碰撞执行事件,当时想了一段时间无果就坑在那啦

后面还是想做完这个,明明那么简单的游戏内容怎么会做不出来?= =
然后。。。。有了以下内容

坑 2021.2.25
sprite不适用于与scrollview结合,换成image+button后完美
不过中间也遇到了很多波折,比如设置image透明部分不可点击,由于素材本身透明部分过多导致与其他部件的不透明部分重叠,最后使得本该能点击的部分也不能点击了
修改方案是,裁剪sprite(原本以为就是在single的选项下裁剪,打开sprite editor后,发现无法slice,尝试修改border后看是否能把图片透明部分裁掉,结果图片无法显示了=_=,最后发现需要修改为multi类型后再去裁剪,并且必须保持为multi类型)
裁剪后,因为使用了trim导致部分同类型的素材大小不一样,而使用gridLayout设置的格子大小又是一样的,会自动匹配相同的宽高,所以还要去把素材大小修改为一致。
当当当!!!0 warrings,0 errors~
解决了以前超级苦恼的问题呢 0


做了点击image跟随的功能,过程中遇到scale模糊而rectsize\Delta.x\sizeDalta.y不是变量无法修改的问题,最后看到文档说明里sizedelta没说不能作为变量就试了下!完美!而且最简单的放大就是之前最先想到的*=1.2f,后面因为忘记结束循环放大过程,还以为写错了

拖动物品
https://blog.csdn.net/qq_37335907/article/details/107951462(需要计算初始的offset)
(overlay模式的话,Camera填null,原因https://blog.csdn.net/qq_40034125/article/details/88029529)

之前遗漏的坑
做2D的游戏,需要用到sprite,会发现UI和sprite不搭嘎,sprite超小,ui和3D一样是独立的一块巨大平面,即使创建的是2D项目,也需要把Canvas改成由camera渲染,canvasScaler设置为scale with screen size

坑坑呜!
后面发现还是要另外生成一个sprite才行,一方面因为脱出布局,原来的里面的元素会改变位置,二方面是因为画布的层级小于sprite(因为要搭背景),而我这里角色是sprite在画布前面,拿image去碰sprite,所以碰撞不到啊喂。(不,我后面一想,我不是拿鼠标位置来做的碰撞吗?所以之前交换失败可能是由于碰到的是image获取不到类别信息??)所以说选择代码的思路也很重要,错误的代码思路让你不得不重新再写过呜呜,这次的坑点在于层级关系,下次要注意了喂,这些细节的参数决定着思路走向哦!(虽然说的很有道理,但是这里原因分析错了啊喂)
另外记录下跨过坑的小tips:
1.实现不了的,考虑是不是有其他方法可以实现,比如sprite改成image,或者image要改成sprite;再比如rect可改成sizedelta;再比如screen坐标(camera)和rectTransform(Canvas)和Transform(word\local)的区别
2.另外创建一个测试项目用于抽象逻辑,但是要注意与原项目的匹配度,如果你要写一堆代码的话,不然就可能导致今天的悲剧(;´д`)ゞ,实装发现思路错了

一点笔记:
sprite的缩放:
1.transform.localscale(这就是它缩放不糊的原因!Σ(っ °Д °;)っ,另外两个一个不能用,一个是特殊情况用)
2.spriterenderer.size(渲染模式为sliced时使用(只需要缩放中心部分的聊天框),需要设置素材的spriteMeshType为fullRect,而不是默认的tight,消耗了一定内存??【透明部分的有无】)
3.renderer.bound.size(只读,所以不能用于缩放)

AudioSource
一个音效只需要一个就够了,可以写在单击按钮调用的函数里,在需要的时候播放

小坑*0*
1.制作粒子效果尾巴:TrailRenderer比粒子效果里的trail好用诶,就是一个问题,不会自己消失,要等一会???不,它俩都不好用,最后发现粒子效果里的Emission的Rate Over Distant最好用!没有延迟,非常顺滑~好像必须要设置为simulation space为world,否则没有效果哦,而基础的正常光点用默认的local就行
2.描边直接加个组件outline就行挺好用的???
3.(针对ui的鼠标进出)ponterTriger组件太麻烦了!!!!原来继承其接口用pointerEnter和Exit就行!!!继承需要调用包、还有继承以后必须实现它的方法,两个方法都要删掉里面原先的代码,是用来提示你把功能写上,不写的话禁止你调用它们哦!(PS:本来想着用onMouseEnter()和onMouseExit()的,看到说uielement也可以,后面去官方api一看!只能给collider(sprite)用啊??!坑死啦Vs的提示原来也不那么可信!还是要看api,估计因为版本众多需要对应api的原因??)
3.打包发布WebGL(2019.4版本):buildsetting注意颜色模式为garmar而不是linear,安装package-WebGL publisher,先build到本地电脑,再在菜单Publish选择build好的本地页面上传给unity官方即可(缺点:需要科学上网才可以打开,否则无法正常显示页面)
4.插值:有时,我们在做游戏时会发现有些跟随动作不够圆滑或者需要一个缓冲的效果,这时,一般会考虑到插值。所以对插值的理解是必需的。(比如摄像机跟随主角)
插值是数学上的一个概念,在这里用公式表示就是:from + (to - from) * t;这也就是Lerp的返回值(用这个公式分别算出x,y,z)。
static function Lerp (from : Vector3, to : Vector3, t : float) : Vector3
from 是起始的位置,to是目标位置,按照数字t在from到to之间插值。
摘自:https://www.cnblogs.com/unity3ds/p/5737183.html
脚本挂在鼠标的粒子效果0v0,看到了大佬做的特效好仙~
public class Cursor : MonoBehaviour
{
public float speed = 8.0f;
public float distanceFromCamera = 5.0f;

void Update()
{
    Vector3 mousePosition = Input.mousePosition;
    mousePosition.z = distanceFromCamera;

    Vector3 mouseScreenToWorld = Camera.main.ScreenToWorldPoint(mousePosition);

    Vector3 position = Vector3.Lerp(transform.position, mouseScreenToWorld, 1.0f - Mathf.Exp(-speed * Time.deltaTime));

    transform.position = position;
}

}

最后为了打包安卓版本,还是改成了拖拽切换。。。就是继承IBeginDrag\IDrag\IEndDrag,把代码拆了分别放进去就好了。。。

你可能感兴趣的:(unity)