Unity游戏基础-6(跨平台生成游戏作品,针对安卓教程)

本教程开始分享教学内容:Unity游戏基础,部分内容会包括Blender建模基础,Shader基础,动画基础等等,教程面向:建模、技术美术、游戏前端、游戏后端基础,适合美术与设计(数媒、环设、动画、产设、视传、绘画)专业、计算机(计算机科学与技术、软件工程、数媒)的同学学习。

本章节为第二章节,面向比较深层次的技术,包括shader基础、跨平台兼容(桌面端、移动端)

一、打开Adobe Illustrator

设计3个图案(摇杆可以使用其他图片替代,后期会专门为摇杆制作效果)

这些图标只在移动端出现,所以我们需要新建一个脚本来处理移动端和桌面端的图标,导出注意要透明

二、打开Unity

按照之前的教程做,我们截图跨平台部分只针对MobileControls操作,然后其他脚本的代码需要修改,修改部分需要认真核对,如果我核对出现错误,请积极指出错误!

1、要善于管理层级关系(直接使用空物体来作为父对象,相当于文件管理的文件夹的作用)

2、导入我们的图片作为控件

建议都放在Texture文件夹里面,注意了,此时的图片文件还不能正常使用,我们点击一个图片文件,在inspector窗口里面把 Texture Type改成Sprite(2D and UI),这样后期我们可以改白色部分的颜色

3、部署控件

(需要4个Image控件,层级关系如上图的MobileControls)

2D场景,去除了setting Form的设计方位,红色摇杆一定要在中间

三、注册事件、新建脚本

通过对控件的Add Components来添加EventTrigger ,疾跑同理

在Script文件夹里面新建一个脚本:PlatformInputManager,并且挂载给backController(黄色底的摇杆底座)

// PlatformInputManager.cs (修改版)
using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class PlatformInputManager : MonoBehaviour
{
    public static PlatformInputManager Instance { get; private set; }

    [Header("移动控制")]
    public MoveControl mobileMoveControl;
    public GameObject mobileControls;

    [Header("平台设置")]
    public bool forceMobile = false;


    private bool isMobilePlatform = false;
    private bool isInitialized = false;

    private bool isjumpdown;
    private bool isSpeed;
    void Awake()
    {
        if (Instance == null)
        {
            Instance = this;
            DontDestroyOnLoad(gameObject);
        }
        else
        {
            Destroy(gameObject);
            return;
        }

        DetectPlatform();
        SetupControls();
        isInitialized = true;
    }

    void DetectPlatform()
    {
        isMobilePlatform = forceMobile ||
                          Application.isMobilePlatform ||
                          Application.platform == RuntimePlatform.Android ||
                          Application.platform == RuntimePlatform.IPhonePlayer;
    }

    void SetupControls()
    {
        if (mobileControls != null)
        {
            mobileControls.SetActive(isMobilePlatform);
        }

        if (!isMobilePlatform)
        {
            Cursor.lockState = CursorLockMode.Locked;
            
        }
        else
        {
            Cursor.lockState = CursorLockMode.None;
            Cursor.visible = true;
        }
    }

    public bool IsMobile()
    {
        return isMobilePlatform;
    }

    public Vector2 GetMovementInput()
    {
        if (!isInitialized) return Vector2.zero;

        if (isMobilePlatform && mobileMoveControl != null)
        {
            return mobileMoveControl.GetInputDirection();
        }
        else
        {
            return new Vector2(
                Input.GetAxis("Horizontal"),
                Input.GetAxis("Vertical")
            );
        }
    }

    public Vector2 GetLookInput()
    {
        if (!isInitialized) return Vector2.zero;

        if (isMobilePlatform)
        {
            return GetMobileLookInput();
        }
        else
        {
            return new Vector2(
                Input.GetAxis("Mouse X"),
                Input.GetAxis("Mouse Y")
            );
        }
    }

    private Vector2 GetMobileLookInput()
    {
        // 简单的触摸输入处理
        if (Input.touchCount > 0)
        {
            Touch touch = Input.GetTouch(0);

            // 只处理在屏幕右半部分的触摸
            if (touch.position.x > Screen.width / 2)
            {
                return touch.deltaPosition * 0.02f; // 灵敏度调整
            }
        }

        return Vector2.zero;
    }

    public void JumpDown()
    {
        isjumpdown = true;
    }
    public void JumpUp()
    {
        isjumpdown = false;
    }

    public void SpeedDown()
    {
        isSpeed = true;
    }
    public void SpeedUp()
    {
        isSpeed = false;
    }
    public bool IsJumpPressed()
    {
        if (!isInitialized) return false;

        if (isMobilePlatform)
        {
            return isjumpdown;
        }
        else
        {
            return Input.GetButtonDown("Jump");
        }
    }

    public bool IsSprintPressed()
    {
        if (!isInitialized) return false;

        if (isMobilePlatform)
        {
           
            return isSpeed;
        }
        else
        {
            return Input.GetKey(KeyCode.LeftShift);
        }
    }

    // 添加一个方法来强制更新控制状态
    public void RefreshControlState()
    {
        SetupControls();
    }
}

设置参数

新建脚本,MoveControl:专门处理移动端摇杆事件,同样地,挂载给backController(黄底底座)

using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class MoveControl : MonoBehaviour, IDragHandler, IPointerUpHandler, IPointerDownHandler
{
    private RectTransform background;
    private RectTransform handle;
    private Vector2 inputDirection;

    public static bool isDragging = false;
    public float HandleRange = 1f;

    public static bool isHandleIn;

    void Start()
    {
        background = GetComponent<RectTransform>();
        handle = transform.GetChild(0).GetComponent<RectTransform>();
        inputDirection = Vector2.zero;
    }
    

    public void OnDrag(PointerEventData eventData)
    {
        isDragging = true;
        Vector2 position = Vector2.zero;

        if (RectTransformUtility.ScreenPointToLocalPointInRectangle(
            background,
            eventData.position,
            eventData.pressEventCamera,
            out position))
        {
            position.x = (position.x / background.sizeDelta.x);
            position.y = (position.y / background.sizeDelta.y);

            inputDirection = new Vector2(position.x * 2, position.y * 2);
            inputDirection = (inputDirection.magnitude > 1) ? inputDirection.normalized : inputDirection;

            handle.anchoredPosition = new Vector2(
                inputDirection.x * (background.sizeDelta.x / 2) * HandleRange,
                inputDirection.y * (background.sizeDelta.y / 2) * HandleRange);
        }
    }

    public void OnPointerDown(PointerEventData eventData)
    {
        OnDrag(eventData);
    }

    public void OnPointerUp(PointerEventData eventData)
    {
        isDragging = false;
        inputDirection = Vector2.zero;
        handle.anchoredPosition = Vector2.zero;
    }

    public Vector2 GetInputDirection()
    {
        return inputDirection;
    }

    public float GetHorizontal()
    {
        return inputDirection.x;
    }

    public float GetVertical()
    {
        return inputDirection.y;
    }
    public bool IsDragging()
    {
        return isDragging;
    }
}

参数设置

其中的private部分可以通过直接挂载摇杆实现,不需要获取子对象

四、修改其他代码

CameraController:Start方法

void Start()
{
    // 确保 PlatformInputManager 已初始化
    if (PlatformInputManager.Instance == null)
    {
        GameObject inputManager = new GameObject("PlatformInputManager");
        inputManager.AddComponent<PlatformInputManager>();
    }

    // 移动端初始设置
    if (PlatformInputManager.Instance.IsMobile())
    {
        Cursor.lockState = CursorLockMode.None;
        isleave = false;
    }
    else
    {
        Cursor.lockState = CursorLockMode.Locked;
    }
//以下代码不变
    Vector3 angles = transform.eulerAngles;
    currentX = angles.y;
    currentY = angles.x;
    targetDistance = distance;
    cameraDirection = (transform.position - target.position).normalized;
}

HandleInput方法部分:

//需要大改
void HandleInput()//整合
{
    // 根据平台获取不同的输入
    if (PlatformInputManager.Instance.IsMobile())
    {
        HandleMobileInput();
    }
    else
    {
        HandleDesktopInput();
    }

    // 限制垂直角度
    currentY = Mathf.Clamp(currentY, minVerticalAngle, maxVerticalAngle);
}

void HandleDesktopInput()//这一部分和上次的相同
{
    // 桌面端输入处理
    currentX += Input.GetAxis("Mouse X") * rotationSpeed;
    currentY -= Input.GetAxis("Mouse Y") * rotationSpeed;

    // 滚轮缩放
    float scroll = Input.GetAxis("Mouse ScrollWheel");
    if (scroll != 0)
    {
        distance -= scroll * zoomSpeed;
        distance = Mathf.Clamp(distance, minDistance, maxDistance);
    }
}

void HandleMobileInput()//专门为移动端写的代码
{
    // 检查是否正在使用摇杆
    //Vector2 joystickInput = PlatformInputManager.Instance.GetMovementInput();
    //isUsingJoystick = joystickInput.magnitude > 0.1f;

    // 处理屏幕旋转(无论是否使用摇杆)
    if (enableTouchRotation && Input.touchCount > 0)
    {
        // 遍历所有触摸点
        for (int i = 0; i < Input.touchCount; i++)
        {
            Touch touch = Input.GetTouch(i);
            // 如果触摸点不在摇杆区域内,则处理为视角旋转
            // 只处理在屏幕右半部分的触摸
            if (touch.position.x > Screen.width / 2 && touch.phase == TouchPhase.Moved)
            {
                currentX += touch.deltaPosition.x * touchSensitivity * mobileRotationMultiplier;
                currentY -= touch.deltaPosition.y * touchSensitivity * mobileRotationMultiplier;

                // 限制垂直角度
                currentY = Mathf.Clamp(currentY, minVerticalAngle, maxVerticalAngle);

            }            
        }
    }

    // 处理双指缩放(无论是否使用摇杆)?
    if (Input.touchCount == 2 & !MoveControl.isDragging)
    {
        Touch touchZero = Input.GetTouch(0);
        Touch touchOne = Input.GetTouch(1);

        Vector2 touchZeroPrevPos = touchZero.position - touchZero.deltaPosition;
        Vector2 touchOnePrevPos = touchOne.position - touchOne.deltaPosition;

        float prevMagnitude = (touchZeroPrevPos - touchOnePrevPos).magnitude;
        float currentMagnitude = (touchZero.position - touchOne.position).magnitude;

        float difference = currentMagnitude - prevMagnitude;

        distance -= difference * zoomSpeed * 0.01f;
        distance = Mathf.Clamp(distance, minDistance, maxDistance);
    }
}

PlayerMovement:几个跳跃、冲刺、需要修改的部分

 void HandleJump()
 {
     if (PlatformInputManager.Instance.IsJumpPressed() && isGrounded)
     {

         playerVelocity.y = Mathf.Sqrt(jumpHeight * -2f * gravity);

     }
 }

 void HandleMovement()
 {
     // 通过PlatformInputManager获取输入
     Vector2 input = PlatformInputManager.Instance.GetMovementInput();
     float horizontal = input.x;
     float vertical = input.y;

     // 如果是移动端,调整移动速度
     float speedMultiplier = PlatformInputManager.Instance.IsMobile() ?
         mobileMoveSpeedMultiplier : 1f;

     // 移动方向计算
     Vector3 camForward = Vector3.Scale(cameraTransform.forward, new Vector3(1, 0, 1)).normalized;
     Vector3 moveDirection = (camForward * vertical + cameraTransform.right * horizontal).normalized;

     // 应用移动速度
     Vector3 movement = moveDirection * moveSpeed * speedMultiplier * Time.deltaTime;
     controller.Move(movement);

     // 角色朝向移动方向
     if (moveDirection.magnitude > 0.1f)
     {
         Quaternion targetRotation = Quaternion.LookRotation(moveDirection);
         float rotationMultiplier = PlatformInputManager.Instance.IsMobile() ?
             mobileRotationMultiplier : 1f;
         transform.rotation = Quaternion.Slerp(
             transform.rotation,
             targetRotation,
             rotateSpeed * rotationMultiplier * Time.deltaTime
         );
     }
     if (isGrounded && playerVelocity.y < 0)
     {
         playerVelocity.y = -2;
     }

     playerVelocity.y += gravity * Time.deltaTime;


     controller.Move(playerVelocity * Time.deltaTime);
 }


void CheckSpeed()
{
    if (PlatformInputManager.Instance.IsSprintPressed())
    {
        moveSpeed = 15f;
    }
    else
    {
        moveSpeed = 5f;
    }
}

五、部署在移动端上

本教程只部署安卓平台,其他跨平台相似,如果你没有安装安卓的SDK可以点击安装

点击Build 选一个文件夹命名为Bin-Android

连接手机数据线,导入,安装,完成!

Unity适用的平台:安卓机器版本不能太老,必须是安卓套壳或者原装安卓系统,鸿蒙系统目前不支持!老版本的安卓不支持,进去是玫红色无法操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值