unity触摸屏多人写字
前言
在多媒体行业的项目中,有一种互动方式是在触摸屏上手写文字(应用于签名、互动写字、涂鸦等),之前尝试性的写了一个多人书写的互动脚本,因为制作过程都是比较基础的,只要对unity引擎有一定的使用经验都能复制出来,这里就不多加赘述了,现在将主要步骤、主要脚本分享给大家。
正文
(1)新建工程,在layer选项新建一个line层,再创建一个相机目标层级line,在LineCam相机下创建子物体Empty,具体如下图:
(2)在Empty下新建物体GameObject,给物体添加组件Line Render,并添加Shader脚本Painting,如下图所示: Painting.shader的脚本如下:
Shader "Painting"
{
Properties
{
_MainTex ("MainTex (RGB) Trans (A)", 2D) = "white" {}
_Color ("Color", Color) = (1,1,1,1)
}
SubShader
{
Tags
{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
}
Cull Off
Lighting Off
ZWrite Off
Fog { Mode Off }
Blend One OneMinusSrcAlpha
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct v2f
{
float4 vertex : SV_POSITION;
half2 texcoord : TEXCOORD0;
};
fixed4 _Color;
v2f vert(appdata_base IN)
{
v2f OUT;
OUT.vertex = UnityObjectToClipPos(IN.vertex);
OUT.texcoord = IN.texcoord;
return OUT;
}
sampler2D _MainTex;
fixed4 frag(v2f IN) : SV_Target{
float4 texColor = tex2D(_MainTex, IN.texcoord);
float value = step(_Color.r + _Color.g + _Color.b, 0.1f);
float4 col = (1 - texColor) * (1 - value) * _Color + texColor * value;
col.a = texColor.a; col.rgb *= col.a;
return col;
}
ENDCG
}
}
}
将相应的图片赋值给Painting这一步就OK了。
3)将myLine.cs脚本挂载,MyLine的内容如下:
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;
using UnityEngine.UI;
[System.Serializable]
public class Paints
{
public Material mat;
public float minWidth;
public float maxWidth;
}
public class MyLine : MonoBehaviour
{
public static MyLine instance;
public Camera LineCam;
public Texture2D tex;
public Paints[] paints;
public int penValue = 0;
public Color penColor;
public GameObject empty;
public float penWidth;
public bool isWrite = false;
public GameObject lineObj;
public Transform par;
private void Awake()
{
instance = this;
}
void Start()
{
isWrite = false;
penWidth = 0.22f;
}
void Update()
{
if (Input.touchCount > 0)
{
for (int i = 0; i < Input.touchCount; i++)
{
switch (Input.touches[i].phase)
{
case TouchPhase.Began:
BeginDraw(Input.touches[i]);
break;
case TouchPhase.Stationary:
case TouchPhase.Moved:
MovedDraw(Input.touches[i]);
break;
case TouchPhase.Canceled:
case TouchPhase.Ended:
EndedDraw(Input.touches[i]);
break;
default: break;
}
}
}
}
Dictionary<int, (int, LineRenderer)> DrawingLineMaps = new Dictionary<int, (int, LineRenderer)>();
List<LineRenderer> DrawedLines = new List<LineRenderer>();
private void EndedDraw(Touch touch)
{
if (DrawingLineMaps.ContainsKey(touch.fingerId))
{
var (index, Line) = DrawingLineMaps[touch.fingerId];
index++;
Line.positionCount = index+1;
var pos = LineCam.ScreenToWorldPoint(new Vector3(touch.position.x, touch.position.y, 0));
pos.z = 0;
Line.SetPosition(index, pos);
DrawingLineMaps.Remove(touch.fingerId);
DrawedLines.Add(Line);
}
}
private void MovedDraw(Touch touch)
{
if (DrawingLineMaps.ContainsKey(touch.fingerId))
{
var (index, Line) = DrawingLineMaps[touch.fingerId];
index++;
Line.positionCount = index+1;
var pos = LineCam.ScreenToWorldPoint(new Vector3(touch.position.x, touch.position.y, 0));
pos.z = 0;
Line.SetPosition(index, pos);
DrawingLineMaps[touch.fingerId] = (index, Line);
}
}
void BeginDraw(Touch touch)
{
if (!DrawingLineMaps.ContainsKey(touch.fingerId))
{
GameObject clone = Instantiate(lineObj, lineObj.transform.position, Quaternion.identity, par);
var line = clone.GetComponent<LineRenderer>();
line.material = paints[penValue].mat;
line.material.SetColor("_Color", penColor);
line.startWidth = penWidth;
line.endWidth = penWidth;
int index = 0;
line.positionCount = index+1;
var pos= LineCam.ScreenToWorldPoint(new Vector3(touch.position.x, touch.position.y, 0));
pos.z = 0;
line.SetPosition(index,pos);
DrawingLineMaps.Add(touch.fingerId, (index, line));
}
}
public void ClearSavePens()
{
if (empty.transform.childCount > 0)
{
for (int i = 0; i < empty.transform.childCount; i++)
{
Destroy(empty.transform.GetChild(i).gameObject);
}
}
}
}
(4)效果演示
|