汽车右侧网格生成

功能说明

汽车右侧的网格包含两种,一种是弧形,另一种是矩形,二者均通过计算坐标位置、顶点个数和UV坐标参数生成所需要的网格,同时对网格进行了适配,根据不同的屏幕分辨率自动缩放网格的大小。

重点代码

 //更新弧形网格   
 protected override void UpdateShape()
 {
    int vertexCount = segment*2 + 2;
    vertices=new Vector3[vertexCount];
    float angle = _angleBegin*Mathf.Deg2Rad;
    float wHalf = ringWidth*0.5f;
    float sin = Mathf.Sin(angle);
    float cos = Mathf.Cos(angle);

    float minRingRadius = _ringRadius - wHalf;
    float maxRingRadius = _ringRadius + wHalf;
    Vector3 localPos = offset;

    float x = cos*minRingRadius + localPos.x;
    float y = localPos.y;
    float z = sin*minRingRadius + localPos.z;

    vertices[0].x = x;
    vertices[0].y = y;
    vertices[0].z = z;

    x = cos*maxRingRadius + localPos.x;
    z = sin*maxRingRadius + localPos.z;

    vertices[1].x = x;
    vertices[1].y = y;
    vertices[1].z = z;

    float singleAngle = (_angleEnd - _angleBegin)/segment*Mathf.Deg2Rad;
    for (int i = 0; i < segment; i++)
    {
        angle += singleAngle;
        sin = Mathf.Sin(angle);
        cos = Mathf.Cos(angle);
        x = cos*minRingRadius + localPos.x;
        y = localPos.y;
        z = sin*minRingRadius + localPos.z;
        vertices[i*2+2]=new Vector3(x,y,z);

        x = cos*maxRingRadius + localPos.x;
        y = localPos.y;
        z = sin*maxRingRadius + localPos.z;
        vertices[i*2+3]=new Vector3(x,y,z);
    }
    UpdateMesh();
}
//更新矩形网格
protected override void UpdateShape()
{
        Vector3 localPos = offset;
        float w2 = m_Width*0.5f;
        float l2 = m_Length*0.5f;

        vertices=new Vector3[4];
        float x0, z0, x1, z1, x2, z2, x3, z3;
        x0 = z0 = x1 = z1 = x2 = z2 = x3 = z3 = 0;

        switch (widthAlign)
        {
            case PivotAlign.Left:
                x0 = 0f;
                x1 = m_Width;
                x2 = 0;
                x3 = m_Width;
                break;
            case PivotAlign.Center:
                x0 = -w2;
                x1 = w2;
                x2 = -w2;
                x3 = w2;
                break;
            case PivotAlign.Right:
                x0 = -m_Width;
                x1 = 0f;
                x2 = -m_Width;
                x3 = 0f;
                break;          
        }
        switch (lengthAlign)
        {
            case PivotAlign.Left:
                z0 = 0;
                z1 = 0;
                z2 = m_Length;
                z3 = m_Length;
                break;
            case PivotAlign.Center:
                z0 = -l2;
                z1 = -l2;
                z2 = l2;
                z3 = l2;
                break;
            case PivotAlign.Right:
                z0 = -m_Length;
                z1 = -m_Length;
                z2 = 0f;
                z3 = 0f;
                break;         
        }

        vertices[0].x = localPos.x + x0;
        vertices[0].y = localPos.y;
        vertices[0].z = localPos.z + z0;

        vertices[1].x = localPos.x + x1;
        vertices[1].y = localPos.y;
        vertices[1].z = localPos.z + z1;

        vertices[2].x = localPos.x + x2;
        vertices[2].y = localPos.y;
        vertices[2].z = localPos.z + z2;

        vertices[3].x = localPos.x + x3;
        vertices[3].y = localPos.y;
        vertices[3].z = localPos.z + z3;
        UpdateMesh();
}

脚本组件属性设置截图

images-p4_2.png

汽车左侧标尺生成

功能说明

标尺左侧的主要功能是用来显示汽车的长、宽和高,并且标尺上带有相关的数据,以方便用户对汽车有一个直观的认识。

脚本组件属性设置截图

//初始化矩形网格
protected override void InitMesh()
{
    if (cacheTransform == null || meshFilter == null)
    {
        Init();
    }
    triangles =new int[] {0,2,3,0,3,1};
    uvs=new Vector2[4];
    uvs[0].x = 0;
    uvs[0].y = 0;
    uvs[1].x = 1;
    uvs[1].y = 0;

    uvs[2].x = 0;
    uvs[2].y = 1;

    uvs[3].x = 1;
    uvs[3].y = 1;
    UpdateShape();
}

//初始化弧形网格
   protected override void InitMesh()
    {
        if (cacheTransform==null||meshFilter==null)
        {
            Init();
        }
        segment = segment > 0 ? segment : 1;
        triangles=new int[segment*2*3];     
        for (int i = 0; i < segment; i++)
        {
            int k = i*6;
            int j = i*2;
            triangles[k] = j;  
            triangles[k + 1] = j + 2;
            triangles[k + 2] = j + 3;
            triangles[k + 3] = j;
            triangles[k + 4] = j + 3;
            triangles[k + 5] = j + 1;
        }
        int vertexCount = segment*2 + 2;
        uvs=new Vector2[vertexCount];
        float singleUV = 1f/segment;
        float uvY = 0f;
        for (int i = 0; i < vertexCount; i+=2)
        {
            uvs[i].x = 0f;
            uvs[i + 1].x = 1f;
            uvs[i].y = uvY;
            uvs[i + 1].y = uvY;
            uvY += singleUV;
        }     
        UpdateShape();   
    }

网格和文字动画

功能说明

通过场景的旋转,汽车左右侧的网格会产生动画,并且有淡入和淡出的效果,通过网格的动画可以吸引客户的注意力,并且能注意到网格上的数据。

重点代码

	//动画正常播放
	private void PlayForward()
    {
        float duration;
        float delay;
        for (int i = 0; i < count; i++)
        {
            duration = Random.Range(minDuration, maxDuration);
            delay = Random.Range(minDelay, maxDelay);
            textTf[i].DOScale(scales[i], duration).SetDelay(delay);
        }
    }
    //动画倒序播放
    private void PlayBackward()
    {
        float duration;
        float delay;
        for (int i = 0; i < count; i++)
        {
            duration = Random.Range(minDuration, maxDuration);
            delay = Random.Range(minDelay, maxDelay);
            textTf[i].DOScale(Vector3.zero, duration).SetDelay(delay);
        }
    }

脚本组件属性设置截图

images-p4_6.png

声音管理

功能说明

当点击LIGHT、EXPLOD和汽车车身的时候,会播放不同的声音,同时汽车分解、车灯移动、汽车变色功能实现时会播放相对应功能的声音。

重点代码

public class SoundManager : MonoBehaviour
{
    public static SoundManager Instance;
    public AudioSource audioSource;
    public AudioClip lightOpen;
    public AudioClip ligthClose;
    public AudioClip explode;
    public AudioClip colorWheel;
    public AudioClip carColorChange;
    void Awake()
    {
        Instance = this;
    }

    void Play()
    {
        audioSource.Play();
    }

    public void PlayLightOpen()
    {
        audioSource.clip = lightOpen;
        Play();
    }

    public void PlayLightClose()
    {
        audioSource.clip = ligthClose;
        Play();
    }

    public void PlayExplode()
    {
        audioSource.clip = explode;
        Play();
    }

    public void PlayColorWheelShow()
    {
        audioSource.clip = colorWheel;
        Play();
    }

    public void PlayCarColorChange()
    {
        audioSource.clip = carColorChange;
        Play();
    }
}

脚本组件属性设置截图

images-p4_8.png

摄像机的变换

功能说明

按下鼠标左键进行左右和上下拖动时,摄像机可以进行左右和上下旋转,实现汽车在场景中旋转的效果,当滚动鼠标的滚轮键时,摄像机视角可以拉近拉远,实现汽车变大变小的效果。

重点代码

	private void Oribit()
    {
        if (Input.GetMouseButtonDown(0))
        {
            lastMousePos = Input.mousePosition;
        }
        if (Input.GetMouseButton(0))
        {
            targetEulerAngle.x += (-Input.mousePosition.y + lastMousePos.y)*cureentCameraParameter.mouseMoveRatio;
            targetEulerAngle.y += (Input.mousePosition.x - lastMousePos.x) * cureentCameraParameter.mouseMoveRatio;
            if (cureentCameraParameter.limitXAngle)
            {
                targetEulerAngle.x = Mathf.Clamp(targetEulerAngle.x, cureentCameraParameter.minXAngle,
                    cureentCameraParameter.maxXAngle);
            }
            if (cureentCameraParameter.limitYAngle)
            {
                targetEulerAngle.y = Mathf.Clamp(targetEulerAngle.y, cureentCameraParameter.minYAngle,
                    cureentCameraParameter.maxXAngle);
            }
            lastMousePos = Input.mousePosition;
        }
        if (Input.touchCount<2)
        {
            eulerAngle = Vector3.Lerp(eulerAngle, targetEulerAngle,
                Time.fixedDeltaTime*cureentCameraParameter.orbitSensitive);
            cameraRootTf.rotation = originalRotate*Quaternion.Euler(eulerAngle);
        }    
        FireEvent(cameraRootTf.localEulerAngles.y);   
    }

脚本组件属性设置截图

images-p4_10.png

广告牌效果

功能说明

该效果使得摄像机无论旋转到任何角度,UI界面都能够把正面面向摄像机,让用户能够完全看到UI界面,该功能也可以用在3D游戏中的血条效果上。

重点代码

   private void SetBillBoardTarget(Transform[] targettfs)
    {
        this.targetTfs = targettfs;
        count = targettfs.Length;
        billBoardItems=new BillBoardItem[count];
        GameObject tempGo;
        for (int i = 0; i < count; i++)
        {
            tempGo = Instantiate(itemObject);
            billBoardItems[i] = tempGo.GetComponent<BillBoardItem>();
            billBoardItems[i].uiText.text = targettfs[i].gameObject.name.Replace("Billboard_", "");
            billBoardItems[i].transform.SetParent(cacheTransform);
            billBoardItems[i].transform.localScale=Vector3.one;
        }
    }

脚本组件属性设置截图

images-p4_12.png

汽车颜色的改变

功能说明

当点击车身时,颜色面板会显示出来,点击颜色面板上的某个色块后,汽车的颜色就会变成所点击色块的颜色。

重点代码

    private void InitBodyChildren()
    {
        Transform[] children = gameObject.GetComponentsInChildren<Transform>();
        int count = children.Length;
        List<ColorItem> colorItems=new List<ColorItem>();
        for (int i = 0; i < count; i++)
        {
            Transform child = children[i];
            if (child!=cacheTransform)
            {
                if (child.name.StartsWith("Body"))
                {
                    child.gameObject.AddComponentIfNotHave<MeshCollider>();
                    EventTriggerListener.Get(child.gameObject).onClick += OnClickBody;
                    ColorItem item = child.gameObject.AddComponent<ColorItem>();
                    colorItems.Add(item);
                }
            }
        }
        items = colorItems.ToArray();
        this.count = items.Length;
    }
    private void OnClickBody(GameObject go, PointerEventData eventdata)
    {
        Debug.Log("点击了"+go.name);
        Vector2 delta = eventdata.position - eventdata.pressPosition;
        if (delta.x<dragData&&delta.y<dragData)
        {
            EventCenter.ConfigEvent.RaiseClickBody(true);
        }
    }

脚本组件属性设置截图

images-p4_14.png

汽车车灯的显示和隐藏

功能说明

当点击屏幕右下角的LIGHT按钮时,按钮上的文字会显示ON,此时车灯会在距车头前面的一定距离显示出来,并移动到汽车头部车灯所在的位置。当再一次点击LIGHT按钮,按钮上的文字显示OFF,此时车灯会从汽车头部移动到车头前面指定的距离并隐藏。

重点代码

	public void ClickButton()
    {
        if (isOpened)
        {       
            EventCenter.UIEvent.RaiseLightFlare(false);   
            anim.Close();
            isOpened = false;
            SoundManager.Instance.PlayLightClose();
        }
        else
        {
            EventCenter.UIEvent.RaiseLightFlare(true);
            anim.Open();
            isOpened = true;
            SoundManager.Instance.PlayLightOpen();
        }
        MouseLock.Instance.Lock(1.5f);
    }

脚本组件属性设置截图

images-p4_16.png

汽车分解

功能说明

当点击屏幕右下角的EXPLOD按钮时,汽车外壳隐藏,只显示内部零件的构造,同时按钮上的文字显示为ON,当再一次点击EXPLOD按钮后,内部零部件隐藏,汽车外壳显示,按钮上的文字显示为OFF。

重点代码

	public void ClickButton()
    {
        if (isOpened)
        {
            Close();
            anim.Close();
            isOpened = false;
            MouseLock.Instance.Lock(1.5f);
        }
        else
        {
            Open();
            anim.Open();
            isOpened = true;
            MouseLock.Instance.Lock(1.5f);
        }
        SoundManager.Instance.PlayExplode();
    }

脚本组件属性设置截图

images-p4_18.png