文字跑馬燈,所先要了解,怎麼顯示模式。

大致上作法 可以用兩種方式來使用。

1. 時間方式計算

2.數字累加

本文採取第二種數字累加的方式來呈現。

邏輯:   數字: 1 代表1個字,表示說 數字累加的方式來顯示文字數量就好了。

本文都採取使用C# 方式來進行編排,不太用到Unity設計界面來操作設定,

但是要先建立需要使用的遊戲物件即可。此篇介面採取比例 (16:9)

使用的遊戲物件:

  • Canvas (Unity UI)
  • Text (Unity UI)
  • EventSystem (Unity UI)
  • Camera

 

完成結果後

image

 

 

 

 

腳本名稱: InterfaceObj

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

// 介面
public class InterfaceObj
{
    // image Obj 
    public Image imageObj(Image image, Color color , float pointX, float pointY, float sizeX, float sizeY)
    {
        image.transform.position = new Vector2(Screen.width / 2 * pointX, Screen.height / 2 * pointY);
        image.rectTransform.sizeDelta = new Vector2(Screen.width / 2 * sizeX, Screen.height / 2 * sizeY);

        image.color = color;

        return image;
    }

    // text Obj
    public Text textObj(Text text, string message, FontStyle fontStyle, Color color ,int textSize, float pointX, float pointY, float sizeX, float sizeY)
    {
        text.text = message;
        text.fontStyle = fontStyle;
        text.color = color;
        text.fontSize = textSize;

        text.transform.position = new Vector2(Screen.width / 2 * pointX, Screen.height / 2 * pointY);
        text.rectTransform.sizeDelta = new Vector2(Screen.width / 2 * sizeX, Screen.height / 2 * sizeY);

        return text;
    }
}

// 介面效果類別
public class interfaceAfterEffects
{
    /*--------------------------
        * 文字效果
    --------------------------*/

    private float marquee_startTime = 0;  // 跑馬燈開始時間

    // 文字跑馬燈
    public void textEffects(TextEffects effects, Text text, string message, float speed, bool start)
    {
        text.text = text_Marquee(message, speed, start);   
    }

    // 跑馬燈
    private string text_Marquee(string message, float speed, bool start)
    {
        return message.Substring(0, (int)text_marquee_timeData(message.Length, speed, start));
    }

    // 計數器(跑馬燈顯示)
    private float text_marquee_timeData(float textSize, float speed, bool start)
    {
        float time = (marquee_startTime < textSize && start.Equals(true)) ? marquee_startTime += speed :
            (start.Equals(false)) ? marquee_startTime = 0 : marquee_startTime = textSize;

        return time;
    }
}

腳本名稱: UI_Layout

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class UI_Layout : MonoBehaviour
{
    InterfaceObj interfaceObj = new InterfaceObj();

    // 文字訊息(系統)
    public void system_mesage_text(Text cameraModel_Text, Text recording_Text, Text InternalLab_Text, Text section8_Text, Text scanning_Text, Text activated, float pointX, float pointY, float sizeX, float sizeY)
    {
        interfaceObj.textObj(cameraModel_Text, "CAMERA 05s", FontStyle.Normal, new Color(0, 0.9f, 1, 1), (Screen.width / 2) / 10, 0.43f, 1.7f, 0.66f, 0.21f);
        interfaceObj.textObj(recording_Text, "REC.", FontStyle.Normal, new Color(1, 1, 1, 1), (Screen.width / 2) / 16, 0.19f, 1.4f, 0.15f, 0.13f);
        interfaceObj.textObj(InternalLab_Text, "INTERNAL LAB 13", FontStyle.Normal, new Color(1, 1, 1, 1), (Screen.width / 2) / 27, 0.55f, 1.44f, 0.32f, 0.1f);
        interfaceObj.textObj(section8_Text, "SECTION 8 - LEVEL 06", FontStyle.Normal, new Color(1, 1, 1, 1), (Screen.width / 2) / 29, 0.58f, 1.33f, 0.38f, 0.08f);
        interfaceObj.textObj(scanning_Text, "SCANNING", FontStyle.Normal, new Color(1, 1, 1, 1), (Screen.width / 2) / 12, 0.34f, 0.85f, 0.47f, 0.18f);
        interfaceObj.textObj(activated, "SYSTEM ACTIVATED", FontStyle.Normal, new Color(1, 1, 1, 1), (Screen.width / 2) / 18, 0.4f, 0.7f, 0.6f, 0.12f);
    }
}

腳本名稱: Layout_Run

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Layout_Run : UI_Layout
{
    public Text cameraModel_Text;
    public Text recording_Text;
    public Text internalLab_Text;
    public Text section8_Text;
    public Text scanning_Text;
    public Text activated_Text;

    // 跑馬燈
    interfaceAfterEffects scanning_Text_marquess = new interfaceAfterEffects();
    interfaceAfterEffects activated_Text_marquess = new interfaceAfterEffects();

    public bool sw = false;

    private void Update()
    {
        systemLayoutMessge();

        if (Input.GetKeyDown(KeyCode.W))
            sw = !sw;
    }

    private void systemLayoutMessge()
    {
   
        system_mesage_text(cameraModel_Text, recording_Text, internalLab_Text, section8_Text, scanning_Text, activated_Text, pointX, pointY, sizeX, sizeY);

        // 文字跑馬燈
        scanning_Text_marquess.textEffects(scanning_Text, "SCANNING", 0.6f, sw);
        activated_Text_marquess.textEffects(activated_Text, "SYSTEM ACTIVATED", 0.4f, sw);

    }
}

文章標籤

Xauxas 發表在 痞客邦 留言(0) 人氣()

Unity 資料寫入MySql做法,大致上兩種做法,一種是透過PHP方式來當媒介方式,進行寫入。

另一種則是透過MySQL Community提供Dll 方式直接寫入。

此篇介紹就是以MySQL Community提供Dll方式來進行實踐,但是會有一些版本的問題存在,此篇 Unity 2018版本

MySQL Community 可到這個網站下載,但是要測試可以用的版本~

為了方面實踐,以下我提供兩個載點:

載點1

載點2  提取码:nunc (也可以掃以下二維碼下載)

CD9527EDCD234A2BC1CBE2FFC085627C

再來就是我們要下載 Xampp了,之記得安裝正確。

Xampp 載點

安裝結束後,打開軟體會呈現這個畫面

螢幕擷取畫面 2021-08-05 045747

再點Admin開啟Mysql 網頁版,建立資料庫與資料表,可以查看Mysql 指令方式來建立。

Mysql 指令許多網站都有整理出來:  凍仁大大整理的筆記之分享(MySql 指令)~~

再此 感謝整理Mysql指令大大的辛苦。

建立資料庫與資料表後,呈現以下圖片 (此篇只建立 ID與姓名)

螢幕擷取畫面 2021-08-05 045747

再來就是程式部分了。

本篇習慣介面物件,都以程式方式來撰寫,比較不會到介面下,進行操作調整。

ScriptName: InterfaceObj  介面物件設定

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Events;

public class InterfaceObj : MonoBehaviour
{
    // 輸入介面
    public InputField inputField(InputField inputField, float pointX, float pointY, float sizeX, float sizeY)
    {
        inputField.transform.position = new Vector2(Screen.width / 2 * pointX, Screen.height / 2 * pointY);
        inputField.image.rectTransform.sizeDelta = new Vector2(Screen.width / 2 * sizeX, Screen.height / 2 * sizeY);

        return inputField;
    }

    // 文字顯示
    public Text text(Text text, string message, float pointX, float pointY, float sizeX, float sizeY)
    {
        text.transform.position = new Vector2(Screen.width / 2 * pointX, Screen.height / 2 * pointY);
        text.rectTransform.sizeDelta = new Vector2(Screen.width/2 * sizeX, Screen.height /2 * sizeY);

        text.text = message;
        text.fontSize = 16;
        text.fontStyle = FontStyle.Normal;
        text.color = Color.black;

        return text;
    }

    // 按鈕
    public Button button(Button button, string btnMessage, UnityAction onClick, float pointX, float pointY, float sizeX, float sizeY)
    {
        button.transform.position = new Vector2(Screen.width / 2 * pointX, Screen.height / 2 * pointY);
        button.image.rectTransform.sizeDelta = new Vector2(Screen.width / 2 * sizeX, Screen.height / 2 * sizeY);

        Text buttonName = button.transform.GetChild(0).GetComponent<Text>();
        buttonName.name = "buttonName";
        buttonName.text = btnMessage;

        button.onClick.AddListener(onClick);

        return button;
    }
}

程式注意: 

using UnityEngine.Events; 要記得匯入,不然按鈕無法進行探聽事件。

  •   UnityAction onClick
  •   button.onClick.AddListener(onClick);

-------------------------------

Script Name: Layout 介面執行

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Layout : InterfaceObj
{
    // 介面物件
    public Button enter_btn;
    public InputField name_Input;
    public Text name_Text;
    public Text disPlayMessage;

    // 輸入數值
    private string name;

    // 查詢介面物件
    public InputField inquireName_Input;
    public Text inquireName_Text;
    public Button inquireEnter_Button;
    public Text inquireDisPlayerMessage;

    // 查詢名稱
    private string inquireName;

    // 資料表名稱
    private string tableName = "member";

    public float pointX, pointY;

    private void Start()
    {
        text(name_Text, "姓名", 0.16f, 1.78f, 0.1f, 0.1f);
        button(enter_btn, "確定", enter_OnClick, 0.79f, 1.8f, 0.3f, 0.15f);

        // 查詢
        text(inquireName_Text, "姓名", 0.16f, 1.23f, 0.1f, 0.1f);
        button(inquireEnter_Button, "查詢", inquireEnter_OnClick, 0.8f, 1.24f, 0.3f, 0.15f);
    }

    private void Update()
    {
        name = inputField(name_Input, 0.43f, 1.8f, 0.4f, 0.15f).text;
        
        // 判斷是否輸入
        if (name_Input.text == "")
            enter_btn.interactable = false;
        else enter_btn.interactable = true;
        
        text(disPlayMessage, "連接資料庫訊息: " + MySqlClass.result + ",  寫入訊息: " + MySqlClass.disPlayerRead, 1f, 1.55f,1.5f, 0.1f);


        // 查詢
        inquireName = inputField(inquireName_Input, 0.43f, 1.24f, 0.4f, 0.15f).text;

        if (inquireName_Input.text == "")
            inquireEnter_Button.interactable = false;
        else inquireEnter_Button.interactable = true;

        text(inquireDisPlayerMessage, "連接資料庫訊息: " + MySqlClass.result + ",  查詢訊息: " + MySqlClass.disPlayInquire, 1f, 1f, 1.5f, 0.1f);
    }

    // 查詢
    void inquireEnter_OnClick()
    {
        openDataBase();

        MySqlClass.INQUIRE_TABLE(tableName, inquireName);
        MySqlClass.closeSqlConnection();
    }

    void enter_OnClick()
    {
        openDataBase();

        MySqlClass.WriteTable(tableName, name);

        MySqlClass.closeSqlConnection();
    }

    private void OnApplicationQuit()
    {
        MySqlClass.closeSqlConnection();
    }

    void openDataBase()
    {
        string connectionString = string.Format("Server = {0}; Database = {1}; UserID = {2}; Password = {3};", MySqlClass.hostType, MySqlClass.dataBaseType, MySqlClass.idType, MySqlClass.passWordTpye);
        MySqlClass.openSqlConnection(connectionString);
        MySqlClass.myObjType = MySqlClass.GetDataSet(connectionString);
    }
}

程式注意:

OnApplicationQuit(); 關閉應用程式的,主要關閉Mysql 連接,如果有寫執行續(Thread)也需要用到。

------------------------------------

Script Name:  MySqlClass 執行資料庫動作

using System.Collections.Generic;
using System.Data;
using System;
using MySql.Data.MySqlClient;
using System.Text;
using UnityEngine;

public class MySqlClass
{
    // Just like MyConn.conn in Story Tolls before
    public static MySqlConnection dbConnection;

    // DataBase Ip
    private static string host = "127.0.0.1";
    public static string hostType
    {
        set { host = value; }
        get { return host; }
    }

    // DataBase user Id
    private static string id = "gsp40214";
    public static string idType
    {
        set { id = value; }
        get { return id; }
    }

    // DataBase Password
    private static string passWord = "123456";
    public static string passWordTpye
    {
        set { passWord = value; }
        get { return passWord; }
    }

    // DataBase Name
    private static string dataBase = "pixnet_test";
    public static string dataBaseType
    {
        set { dataBase = value; }
        get { return dataBase; }
    }

    // 連線結果
    public static string result = "";

    // 寫入結果
    public static string disPlayerRead = "";

    // 查詢結果
    public static string disPlayInquire = "";

    // DataSet
    private static DataSet myObj;
    public static DataSet myObjType
    {
        set { myObj = value; }
        get { return myObj; }
    }

    // Connect to database
    public static void openSqlConnection(string connectionString)
    {
        dbConnection = new MySqlConnection(connectionString);
        dbConnection.Open();
        result = dbConnection.ServerVersion;
    }

    // closeSql
    public static void closeSqlConnection()
    {
        dbConnection.Close();
        dbConnection = null;
    }

    // MySQL Query
    public static void doQuery(string sqlQuery)
    {
        IDbCommand dbCommand = dbConnection.CreateCommand();
        dbCommand.CommandText = sqlQuery;
        IDataReader reader = dbCommand.ExecuteReader();
        reader.Close();
        reader = null;
        dbCommand.Dispose();
        dbCommand = null;
    }

    #region Get DataSet
    public static DataSet GetDataSet(string sqlString)
    {
        DataSet ds = new DataSet();

        try
        {
            MySqlDataAdapter da = new MySqlDataAdapter(sqlString, dbConnection);
        }
        catch (Exception e)
        {
            throw new Exception("SQL:" + sqlString + "\n");
            e.Message.ToString();
        }
        return ds;
    }
    #endregion

    // 轉utf8
    public static string messageToUtf8(string message)
    {
        UTF8Encoding encoder = new UTF8Encoding();
        byte[] bytes = Encoding.UTF8.GetBytes(message);
        string utf8ReturnString = encoder.GetString(bytes);

        return utf8ReturnString;
    }

    static string ID;
    static string Message;

    // 寫入資料表
    public static void WriteTable(string DataBaseTable, string message)
    {
        MySqlCommand command = dbConnection.CreateCommand();

        string sqlText = "select count(1) from " + DataBaseTable + " where name=('" + message + "')";

        MySqlCommand cmd1 = new MySqlCommand(sqlText, dbConnection);
        int count = (int)(long)cmd1.ExecuteScalar();

        if (count > 0)
        {
            Debug.Log("已經有資料囉");
            disPlayerRead = "已經有資料囉";

        }
        else
        {         
            Message = messageToUtf8(message);

            command.CommandText = "Insert into " + DataBaseTable + "(id, name) value('" + ID + "','" + Message + "')";
            command.ExecuteNonQuery();

            disPlayerRead = "載入資料成功";
            Debug.Log("載入資料成功");
        }
    }

    // 資料庫查詢
    public static void INQUIRE_TABLE(string dataBaseTitle, string message)
    {
        string sqlText = "select * from " + dataBaseTitle + " where name='" + message + "'";

        MySqlCommand cmd = new MySqlCommand(sqlText, dbConnection);
        MySqlDataReader data = cmd.ExecuteReader();

        while (data.Read())
        {
            try
            {
                disPlayInquire = "資料庫裡面有資料: " + data[1];
            }
            catch (Exception e)
            {
                data.Close();
                closeSqlConnection();
            }
        }

        data.Close();
    }
}

程式注意:

"Insert into " + DataBaseTable + "(id, name) value('" + ID + "','" + Message + "')";  資料庫寫入語法

"select * from " + dataBaseTitle + " where name='" + message + "'";   資料庫查詢語法

 data[1]; 裡面數字代表資料表欄位編號。

如果MySQL有增加新的使用者記得設定權限,否則也會連接失敗。

----------------------------------

發佈後 執行結果: 

寫入資料庫,記得Mysql 網頁重新整理~

image

如果我們要查詢資料庫是否有小花結果:

image

 

如果發現到發佈之後,無法寫入資料庫,但是在Unity軟體上執行正常,表示缺少Dll 檔案。

缺少檔案: 可以到Unity安裝路徑下:

Unity → Editor → Data → Mono → lib → mono → 2.0 

I18N的相關檔案複製到Unity專案目錄下貼上試試。

 

文章標籤

Xauxas 發表在 痞客邦 留言(0) 人氣()

上一篇 有提到Unity 寫入Excel 基本功能,延續上一篇的方法來實踐有趣的事情吧。

這次 我們會使用Unity UI 功能,來方便設計基本的介面設定。

此篇由程式方式來設定UI設定,比較方便,不用到版面慢慢設定的麻煩。

首先 我們要先知道,我們介面需要使用甚麼物件來進行。

此篇使用物件: Text, InputField, Button

因此建立 UI Class 來方式來撰寫物件設定的功能

Script Name: UIClass

 

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Events;

public class UIClass : MonoBehaviour
{
    public InputField inputField(InputField obj, float pointX, float pointY, float sizeX, float sizeY){
  
        obj.transform.position = new Vector2(Screen.width / 2 * pointX, Screen.height /2 * pointY);
        obj.image.rectTransform.sizeDelta = new Vector2(Screen.width / 2 * sizeX, Screen.height / 2 * sizeY);
  
        return obj;
    }
  
    public Text text(Text text, string message, float pointX, float pointY, float sizeX, float sizeY, Color color, int textSize, FontStyle fontStyle){
        
        text.transform.position = new Vector2(Screen.width /2 * pointX, Screen.height /2 * pointY);
        text.rectTransform.sizeDelta = new Vector2(Screen.width / 2 * sizeX, Screen.height / 2 * sizeY);
  
        text.text = message;
        text.fontSize = textSize;
        text.fontStyle = fontStyle;
        text.color = color;
  
        return text;
    }
  
    public Button button(Button button, string button_Name, float pointX, float pointY, float sizeX, float sizeY, UnityAction onClick){
  
        button.transform.position = new Vector2(Screen.width / 2 * pointX, Screen.height /2 * pointY);
        button.image.rectTransform.sizeDelta = new Vector2(Screen.width / 2 * sizeX, Screen.height / 2 * sizeY);
  
        GameObject buttonName = button.transform.GetChild(0).gameObject;
        buttonName.name = "button_Name";
        buttonName.GetComponent<Text>().text = button_Name;
        
        button.onClick.AddListener(onClick);
  
        return button;
    }
}

 

程式部分: 

1. UnityAction - (記得匯入) using UnityEngine.Events; 

※ 由於Unity UI Button 是兩個物件: button與Text物件形成父子物件,為了好分辨,用程式直接進行修改,就不用針對一個一個物件慢慢修改。

2. GameObject buttonName = button.transform.GetChild(0).gameObject;

  •     buttonName.name = "button_Name";
  •     buttonName.GetComponent<Text>().text = button_Name

-------------------------------------------------------------------------------

Script Name : Layout

 

using UnityEngine;
using UnityEngine.UI;
using System;

public class Layout : UIClass
{
    public InputField year_inputField, month_inputField, company_inputField;
    public Text year_text, month_text, company_text;
  
    public Button enter_btn, quit_btn;
  
    ClassSchedule classSchedule;
  
    private void Start() {
  
        button_function();
    }
  
    private void Update() {
        layout_();
    }
  
    // 按鈕
    void button_function(){
  
         // 按鈕: 建立班表與應用程式離開
        button(enter_btn, "建立班表格式", 1.3f, 0.3f, 0.3f, 0.2f, Enter_Onclick);
        button(quit_btn, "結束應用程式", 1.7f, 0.3f, 0.3f, 0.2f, Quit_Onclick);
    }
  
    // 介面
    void layout_(){
        
        // 年
        inputField(year_inputField, 0.3f, 1.7f, 0.3f, 0.2f);
        text(year_text, "年", 0.5f, 1.7f, 0.05f, 0.07f, Color.white, 16, FontStyle.Normal);
  
        // 月
        inputField(month_inputField, 0.9f, 1.7f, 0.3f, 0.2f);
        text(month_text, "月", 1.1f, 1.7f, 0.05f, 0.07f, Color.white, 16, FontStyle.Normal);
  
        // 公司名稱
        inputField(company_inputField, 1.65f, 1.7f, 0.3f, 0.2f);
        text(company_text, "公司名稱", 1.36f, 1.7f, 0.14f, 0.07f, Color.white, 16, FontStyle.Normal);
    }
  
    void Enter_Onclick(){
  
        classSchedule = new ClassSchedule(Int32.Parse(year_inputField.text), Int32.Parse(month_inputField.text), company_inputField.text, "行政");
  
        classSchedule.classShedule_Fixed();
    }
  
    void Quit_Onclick(){
        Application.Quit();
    }
}

 

程式部分:

1.  classSchedule = new ClassSchedule(Int32.Parse(year_inputField.text), Int32.Parse(month_inputField.text), company_inputField.text, "行政");

※ 也可以直接進行ClassSchedule 指定參數,不建議使用。

2. button(enter_btn, "建立班表格式", 1.3f, 0.3f, 0.3f, 0.2f, Enter_Onclick);  -  Enter_Onclick : 直接寫成方法來探聽即可。

-------------------------------------------------------------------------------

Script Name : classShedule_Fixed

 

using System;
using System.IO;
using OfficeOpenXml;
using Drawing = System.Drawing;

public class ClassSchedule
{
    private int _year, _month;
    private string _companyName, _unit;
   
    public ClassSchedule(int year, int month, string companyName, string unit)
    {
        this._year = year;
        this._month = month;
        this._companyName = companyName;
        this._unit = unit;
    }
  
    // 建立資料位置
    private string folderPath = @"D:\班表\";
  
    // 檔案路徑
    private string filePath;                                             
  
    // Excel 固定格式
    int companyNameYear = 1;  // 年
    int positionNumber = 2;  // 職位
    int dayExcelNuber = 3;   // 天
  
    // excel 組件
    ExcelPackage excelPackage;
    ExcelWorksheet workSheets;
  
    // 每年每月類別
    QueryMonthAndDays queryMonthAndDays;
  
    // 檔案類別
    FileInfo fileInfo;
  
    public void classShedule_Fixed(){
  
        // 建立資料夾與檔案位置
        createExcelFile();
  
        queryMonthAndDays = new QueryMonthAndDays(_year, _month, 1);
  
        excelPackage = new ExcelPackage(fileInfo);
        workSheets = excelPackage.Workbook.Worksheets.Add(queryMonthAndDays.getData()[0].month + "月");
  
        // 寫入公司名稱
        workSheets.Cells[companyNameYear, 1].Value = queryMonthAndDays.getData()[0].year + "年" + queryMonthAndDays.getData()[0].month + "月 " + _companyName + " (" + "單位: " + _unit + ")";
        workSheets.Cells[companyNameYear, 1, 1, queryMonthAndDays.getData().Count + 3].Merge = true;
  
        // 寫入單位
        workSheets.Cells[positionNumber, 1].Value = _unit;
        workSheets.Cells[positionNumber, 1, positionNumber, queryMonthAndDays.getData().Count + 3].Merge = true;
  
        tableColor(positionNumber, 1, Drawing.Color.Yellow);
  
                // 寫入年月與公司名稱
        foreach (var dayweekData in queryMonthAndDays.getData())
        {
            workSheets.Cells[dayExcelNuber, 1].Value = "員工";
            // 天與週次
            workSheets.Cells[dayExcelNuber, Int32.Parse(dayweekData.day) + 1].Value = dayweekData.week + dayweekData.day;
  
            // 休假
            workSheets.Cells[dayExcelNuber, Int32.Parse(dayweekData.day) + 2].Value = "休假";
            // 表格上色
            tableColor(dayExcelNuber, queryMonthAndDays.getData().Count + 2, Drawing.Color.Red);
  
            //加班
            workSheets.Cells[dayExcelNuber, Int32.Parse(dayweekData.day) + 3].Value = "加班";
        }
  
        excelStyle(companyNameYear, 1, dayExcelNuber, queryMonthAndDays.getData().Count + 3);
        excelPackage.Save();
    }
        // excel 樣式
    void excelStyle(int fromRow, int fromCol, int toRow, int toCol)
    {
        // 字形
        workSheets.Cells.Style.Font.Name = "標楷體";
        // 文字大小
        workSheets.Cells.Style.Font.Size = 16;
        // 水平置中
        workSheets.Cells.Style.HorizontalAlignment = OfficeOpenXml.Style.ExcelHorizontalAlignment.Center;
        // 垂直中
        workSheets.Cells.Style.VerticalAlignment = OfficeOpenXml.Style.ExcelVerticalAlignment.Center;
        // 表格框線
        workSheets.Cells[fromRow, fromCol, toRow, toCol].Style.Border.Bottom.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thick;
        workSheets.Cells[fromRow, fromCol, toRow, toCol].Style.Border.Top.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin;
        workSheets.Cells[fromRow, fromCol, toRow, toCol].Style.Border.Left.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin;
        workSheets.Cells[fromRow, fromCol, toRow, toCol].Style.Border.Right.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin;
    }
  
    // Drawing
    void tableColor(int fromRow, int fromCol, Drawing.Color color)
    {
        workSheets.Cells[fromRow, fromCol].Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid;
        workSheets.Cells[fromRow, fromCol].Style.Fill.BackgroundColor.SetColor(color);
    }
  
    // 建立檔案
    private void createExcelFile()
    {
        // 建立資料夾
        if (!Directory.Exists(folderPath + @"\" + _unit))
            Directory.CreateDirectory(folderPath + @"\" + _unit);
  
        // 判斷檔案是否存在
        if (fileExist())
        {
            fileInfo.Delete();
            fileInfo = new FileInfo(filePath);
        }
  
    }
  
    // 檔案是否存在
    bool fileExist()
    {
        filePath = folderPath + @"\" + _unit + @"\" + _year.ToString() + "年" + _month.ToString() + "月" + ".xlsx";
        fileInfo = new FileInfo(filePath);
  
        bool fileExist = fileInfo.Exists;
  
        return fileExist;
    }
}

 

程式部分:

1. using Drawing = System.Drawing -  記得Unity 專案匯入System.Drawing.dll 才能執行

2. excelPackage = new ExcelPackage(fileInfo) -  檔案位置

3. workSheets = excelPackage.Workbook.Worksheets.Add(queryMonthAndDays.getData()[0].month + "月") - Excel 活頁簿

4. excelStyle(companyNameYear, 1, dayExcelNuber, queryMonthAndDays.getData().Count + 3) - excelStyle(X位置, Y軸位置, X幾格, Y幾格)

5. excelPackage.Save(); - Excel 寫入後存檔

-------------------------------------------------------------------------------

Unity 介面部分

GameObjcet :

  1. Main Camera
  2. EventSystem
  3. Canvas:   
    • Year_text -Text
    • Year_inputField - InputField
    • Month_text - Text
    • Month_inputField - InputField
    • Company_text - Text
    • Company_inputField - InputField
    • Enter_btn - Button
    • Quit_btn - Button

那些物件不用設定任何事情,只需要改名及把Layout 腳本放到Canvas物件中。

螢幕擷取畫面 2021-05-19 045114

Layout 腳本顯示Public 物件名稱放入場景物件

再來調整製作過程需要的解析度,本版主習慣用 16:9 的比例來做專案,除非遊戲企劃規定,依據更改。

image

※ 順便一提: 此篇沒有UI 介面設計,單位輸入的,如果使用者需要可以自行加入。

以上設定好後,就可以試試了,以下執行結果。

image

螢幕擷取畫面 2021-05-19 045114

 

 

文章標籤

Xauxas 發表在 痞客邦 留言(0) 人氣()

Unity 底下操作寫入Excel 檔案且匯出xlsx 副檔名,並且需要前置工作,否則匯入dll檔案會導致Unity 錯誤,如果少了dll 檔案發佈專案後,也會導致無法正常輸入Excel 檔案。

當然在正常遊戲設計領域,很少會使用到這項功能,但是 Unity 強項,並非只有在製作遊戲上面哦。

以下來進行,今天主題的內容如何實踐吧~

所先要下載,可以製作Excel方式來進行方便開發。

Excel 全部相關DLL下載   提取碼: 0xso  /  備用載點

所使用的工具 EPPLUS 組件方式,來方便撰寫。

Dll 載入Unity中,會出現一些紅字問題。

如下圖:

image

那個問題是Unity 表示,無法讀取 .Net Standard 2.0 API, 因此需要設定專案。

操作方式為: File/Build Setting....(快捷鍵 : ctrl +shift +b),會出現 Bulid setting 視窗

Visual Studio code 組件圖示

再設定 API Compatibility Level 選項選擇 .Net4.0 (文章Unity 版本: 2018)

Visual Studio code 組件圖示

選擇完後,錯誤紅字就會消失,如果還有出現錯誤請刪除 System.Data.dll 這個檔案即可。

再來 我們就來測試一下是否,可以正常寫入與讀取匯出。

我查詢了許多相關資訊,也是有很多方式,覺得比較複雜,這裡提供簡單方式來進行。

再來就是程式部分了 呵呵~

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Excel;
using OfficeOpenXml;
using System.IO;

public class ExcelTest : MonoBehaviour
{
    public string filePath = @"C:\Users\user\Desktop\123.xlsx";
    FileInfo fileInfo;
    ExcelPackage package;
    ExcelWorksheet worksheet;
    string str = "";
  private void OnGUI() {      
        
      // 寫入Excel 檔案裏面內容
      if(GUILayout.Button("寫入Excel 檔案內容"))
        writeExcel();
  
      if(GUILayout.Button("讀取 Excel 檔案名稱")){
          str = readExcel();
      }
       
     GUILayout.Label("測試: " + str);
  }
  
  // 讀取 Excel  檔案
  string readExcel(){
      
      string result = "";
  
      fileInfo = new FileInfo(filePath);
  
      package = new ExcelPackage(fileInfo);
  
      worksheet = package.Workbook.Worksheets["Test"];
  
      string str = worksheet.Cells[1, 1].Text;
      string str1 = worksheet.Cells[2, 1].Text;
      string str2 = worksheet.Cells[3, 1].Text;
  
      result = str + str1 + str2;
  
      return result;
  }
  
  // 寫入Excel 檔案
  void writeExcel(){
      
      fileInfo = new FileInfo(filePath);
  
      if(fileInfo.Exists){
  
          fileInfo.Delete();
          fileInfo = new FileInfo(filePath);
        }
  
      fileInfo = new FileInfo(filePath);
      package = new ExcelPackage(fileInfo);
      
      worksheet = package.Workbook.Worksheets.Add("Test");
      
      worksheet.Cells[1, 1].Value = "ID";
      worksheet.Cells[2, 1].Value = "小名";
      worksheet.Cells[3, 1].Value = "小花";
  
      package.Save();
  }
}

程式部分解釋:

Excel 裡面表格,可以看成 X, Y 座標的方式來進行。

string str = worksheet.Cells[1, 1].Text; 

以上那段程式解釋 string 負責接值由worksheet.cells.text 來傳值。

會發現到Cells[1, 1] 裡面顯示1,1 那個表示Excel 表格位置,當然也可以直接寫成Cells[A1],只是不建議就是了。

主要是寫成A1的話,是直接指定,如果多筆資料要一個一個指定較麻煩,不如使用迴圈條件來進行寫入較方便。

這段程式: worksheet = package.Workbook.Worksheets["Test"];  是Excel 活頁簿 ,因此Excel 必要有活頁簿才能進行執行。

----------------

結果圖如下:

Unity 發佈與未發佈,執行結果是會有差距的。

因此需要發佈執行為主。

Visual Studio code 組件圖示

 

 

文章標籤

Xauxas 發表在 痞客邦 留言(0) 人氣()

Unity 讀取年月日,並顯並不是難事,只要使用 System.DateTime 函式庫就可以了。

顯示設定當下月份天數,比較少用到這個功能,除非班表功能(讓使用者)才會使用的上。

那我們趕快進入程式碼部分吧

這段程式:  resultDisPlayer(int year, int month, int day) 為了方便使用者開發,

可以透過UI介面或者Unity GUI (過去式介面) 來進行溝通。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;

public class TestScript : MonoBehaviour
{
    DateTime startdate;
  
    // Start is called before the first frame update
    void Start()
    {
        Debug.Log(resultDisPlayer(2021, 5, 1));        
    }
  
    string resultDisPlayer(int year, int month, int day){
  
        string result = "";
  
        startdate = new DateTime(year, month, day);
  
        for (int x = day; x <= DateTime.DaysInMonth(startdate.Year, startdate.Month); x++)
        {
 
            startdate = new DateTime(startdate.Year, startdate.Month, x);
  
            string str = "民國: " + vidToRepublic(startdate.Year) + "年 " 
                + startdate.Month + "月 " + x + "日 " + "星期: " + weekEngToChin(startdate.DayOfWeek.ToString());
  
            result += str + "\n";
        }
  
        return result;
  
    }
  
    // 西元轉換民國 (公式)
    string vidToRepublic(int dayofYear)
    {
        int vidNumber = 1911; // 公式
  
        int sum = dayofYear - vidNumber;
  
        return sum.ToString();           
    }
  
    // 英文轉中文(星期)
    string weekEngToChin(string dayOfWeek)
    {
        string chinWeek = "";
  
        if (dayOfWeek.ToString().Equals("Monday"))
            chinWeek = "星期一";
        if (dayOfWeek.ToString().Equals("Tuesday"))
            chinWeek = "星期二";
        if (dayOfWeek.ToString().Equals("Wednesday"))
            chinWeek = "星期三";
        if (dayOfWeek.ToString().Equals("Thursday"))
            chinWeek = "星期四";
        if (dayOfWeek.ToString().Equals("Friday"))
            chinWeek = "星期五";
        if (dayOfWeek.ToString().Equals("Saturday"))
            chinWeek = "星期六";
        if (dayOfWeek.ToString().Equals("Sunday"))
            chinWeek = "星期日";
  
        return chinWeek;
    }
}

顯示結果如下:

image

 

文章標籤

Xauxas 發表在 痞客邦 留言(0) 人氣()

目前 很夯 Visual Studio Code  來撰寫程式,主要是開啟速度較快與程式撰寫者,可自行匯入模組,那我們如何進行用 Visual Studio Code 來撰寫Unity底下程式。

如步驟以下:

官方連結:  Visual Studio Code

下載完成後_介面如下:

 

 

 

 

 

 

 

 

 

 

Unity開發,這裡使用 C#語言來撰寫,因此下載 .NET Core SDK 工具來協助方便撰寫。

官方連結: .NET Core SDK

再到此圖紅色框框點選下載

 
 
下載安裝後,在安裝常用組件:
 
 
 
 
 
 
再到Unity3D 軟體,設定程式腳本編譯器選擇
 

 

 
 
 
 
 
 
 
 
 
 
 

 

 

 

 

 

 

 

 

 

出現以下圖片結果表示成功了  

 

 

 

 

 

 

 

若沒辦法顯示,請進行重新開機即可。

文章標籤

Xauxas 發表在 痞客邦 留言(0) 人氣()

程式碼來源: https://blog.csdn.net/BIGMAD/article/details/71698310

---- 以下是編輯路徑腳本 ----

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EditorPathScript : MonoBehaviour {

    public Color rayColor = Color.red;
    public List path_objs = new List();
    Transform[] theArray;

    void OnDrawGizmos(){
        Gizmos.color = rayColor;
        theArray = GetComponentsInChildren();
        path_objs.Clear();
        foreach(Transform path_obj in theArray){
            if(path_obj != this.transform)
                path_objs.Add(path_obj);
        }

        for(int i = 0;i0){
                Vector3 previous = path_objs[i-1].position;
                Gizmos.DrawLine(previous,position);
                Gizmos.DrawWireSphere(position, 0.3f);
            }
        }
    }
}

 

 

20170511212047659.png

---- 以下是物件跟隨行為腳本 ----

using UnityEngine;
using System.Collections;

public class FollowPath : MonoBehaviour {

    public bool StartFollow = false;
    public EditorPathScript PathToFollow;
    public int CurrentWayPointID = 0;
    public float Speed;//移动速度
    public float reachDistance = 0f;//里路径点的最大范围
    public string PathName;//跟随路径的名字
    private string LastName;
    private bool ChangePath = true;



    void Start () {

    }

    void Update () {
        if (!StartFollow)
            return;
        if (ChangePath)
        {
            PathToFollow = GameObject.Find(PathName).GetComponent();
            ChangePath = false;
        }
        if (LastName != PathName)
        {
            ChangePath = true;
        }
        LastName = PathName;




        float distance = Vector3.Distance(PathToFollow.path_objs[CurrentWayPointID].position, transform.position);
        //transform.Translate(PathToFollow.path_objs[CurrentWayPointID].position * Time.deltaTime * Speed, Space.Self);
        transform.position = Vector3.MoveTowards(transform.position, PathToFollow.path_objs[CurrentWayPointID].position, Time.deltaTime * Speed);
        if (distance &lt;= reachDistance)
        {
            CurrentWayPointID++;
        }
        if (CurrentWayPointID &gt;= PathToFollow.path_objs.Count)
        {
            CurrentWayPointID = 0;
        }
    }
}

 

20170511212205142.png

文章標籤

Xauxas 發表在 痞客邦 留言(0) 人氣()

Repy 遊戲開發引擎,屬於商業開源的引擎,許多GalGame或其他以CG圖18禁遊戲最多,

RenPy 也有許多網站也有教學

-----以下兩個網站-----------------------------------

《雪凡與好朋友們的Ren'Py 遊戲引擎初學心得提示》

RenPy中文空间- Ren'Py视觉小说引擎技术研究与分享!

-------------------------------------------------------

官方下載

擷取.PNG

這邊只下載Download SDK 7z.exe (72MB) 這個選項。

但是漢化只能針對腳本的方式來做使用,

若是圖片則是無法漢化,進行圖片更改才行。

這邊就拿 Black Monkey 這款「腐女」有一定的人氣的作品來這次的範例,剛好在幫人漢化。

在做漢化之前,各位下載一下編譯器(撰寫程式軟體)及UnRen (反編譯軟體)。

---------------------------------------------

推薦的編譯器:

1. Visual Studio code  

2. Editra 

1. Visual Studio code 微軟的編譯器

功能強大的編譯器,可支援多方面語言,

若是沒有此遊戲設計工具,可以擴充進去。

 

2. Editra 內建的,當然如果不想到官方連結下載,

可以透過RenPy 遊戲開發引擎的編輯檔案,

隨便選擇一個腳本,就會顯示一個Editor 選項,

點下去就可以下載了。

 

反編譯軟體:

1. UnRen

---------------------------------------------

如果準備好了,我們就開始吧~~

首先我們先打開RenPy遊戲引擎,介面大概呈現以下圖片....

擷取.PNG

之後我們可以從下面的設定方式來進行專案位置更改。

擷取.PNG

更改好路徑後,請按下返回,之後建立專案,就會發現到剛剛建立專案的名稱 (這不是廢話嗎 XD~~

擷取.PNG

 

接下來就是專案內容有哪些檔案,之後我們就可以直接把要漢化遊戲的檔案丟進去就好了.....

雖然邏輯是正確,但是缺少了一個很重要的步驟就是忘記反編譯了....

專案內容有「Game資料夾」點下去就可以看到與圖片相同內容....

Black Monkey 遊戲 資料夾內容...

擷取.PNG

再來就是一個很重要的步驟,請把UnRen 解壓縮到遊戲Game裡面的資料夾後....

之後執行UnRen.bat檔案,來進行反編譯程序。

請按下鍵盤上的「9」後按下Enter,全部反編譯出來,之後就等他反編譯完成,反編譯結束就可以關掉視窗。

之後就會發現到Game資料夾多了一大推的rpy副檔名檔案。

之後Game資料夾的所有內容複製到專案Game資料夾內容,如果要「取代」就「取代」吧。

再來開啟RenPy遊戲開發引擎後,點選啟動專案,測試看看是否成功....

如果成功就完成50%工作量..... 剩下就是漢化的問題了.....

接下來就回到RenPy 開發軟體,再來看編輯檔案....

會有「Script.rpy」故事劇情、「Screen.rpy」功能選項、「gui.rpy」遊戲介面環境設定。

如果有安裝Editra 軟體就可以直接針對RenPy編輯檔案直接點取,若是其他編譯器則要到專案Game資料夾底下選擇檔案開啟。

如果學過基礎的程式設計,就會知道 " " 這個符號就是字串,我們就針對字串來進行漢化吧。

 

遊戲執行結果如下,會產生亂碼,是很正常,主要測試是否可以漢化而已。

如果不行漢化,可能路徑或反編譯過程當中....操作錯誤。

剩下就是編碼問題了,中文的話...有做過記事本解碼,直覺一定改成Unicode方式進行解碼,但是遊戲會發生錯誤哦。

因此不能隨意更改解碼格式(utf-8)。

那怎麼樣才能解決亂碼問題呢,每款遊戲開發者設定架構都不同,因此要注意Game資料夾底下檔案內容,才能知道。

以Black Monkey 這款遊戲來說,他會有一個「characters.rpy」這個腳本,其餘遊戲可能沒有。

每一位角色透過字型方式來顯示,文字效果。

如果是繁體中文,可以到系統下的Font資料夾來進行字型上的複製到專案底下「Game/font」貼上。

可以用ctrl + F 快捷鍵方式來尋找 .ttf 檔案來進行更改。( 簡直廢話......XD

因此 :  what_font = "font/not just groovy.ttf" 應更改為 what_font = "font/字型名稱.ttf"

更改完....再回到RenPy 執行專案,就會發現到已經漢化成功。

但是為了保險起見....會建議在「gui.rpy」檔案,做一下字型上的設定,一樣用Ctrl + F 尋找到 Fonts。

可以找到以下三段:

遊戲內容字型:  define gui.text_font = "SourceHanSans-Light-Lite.ttf"                     
角色名稱字型:  define gui.name_text_font = "SourceHanSans-Light-Lite.ttf"

介面名稱:  define gui.interface_text_font = "SourceHanSans-Light-Lite.ttf"

更改為: define gui.text_font = "font/字型名稱.ttf"

建議順便也更改字型吧,可以完成了。

---------------------------------------------------------------

也有網路上的大大提出解決亂碼的方式

「Script.rpy」初始地方貼上。

  1. init:
  2.  
    $ style.default.font = "字型路徑.ttf"
  3. init python:
  4.  
     
       style.default.layout = "greedy"

 

「gui.rpy.rpy」fonts 位置更改字型路徑即可。

  define gui.text_font = "字型路徑.ttf"   

  define gui.name_text_font = "字型路徑.ttf" 

  define gui.interface_text_font = "字型路徑.ttf"

  此方法,這裡沒有測試過,如果有大大測試過,可以提出看法

  小弟我在這裡感激不盡。

 ---------------------------------------------------------------

文章標籤

Xauxas 發表在 痞客邦 留言(0) 人氣()

此文章內容則是以Unity來製作Android系統讓手機產生震動的效果。

---------------

Script (C#):

 

using System.Collections;
using UnityEngine;

public static class Vibration
{
#if UNITY_ANDROID && !UNITY_EDITOR
    public static AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
    public static AndroidJavaObject currentActivity = unityPlayer.GetStatic("currentActivity");
    public static AndroidJavaObject vibrator = currentActivity.Call("getSystemService", "vibrator");

#else
    public static AndroidJavaClass unityPlayer;
    public static AndroidJavaObject currentActivity;
    public static AndroidJavaObject vibrator;
#endif

    private static bool isAndroid()
    {
#if UNITY_ANDROID && UNITY_EDTOIR
        return true;
#else
        return false;
#endif
    }

    /// 

    /// 震動
    /// 
    public static void Vibrate()
    {
        if (isAndroid())
            vibrator.Call("vibrate");
        else
            Handheld.Vibrate();      
    }

    /// 

    /// 震動(毫秒)
    /// 
    /// 
    public static void Vibrate(long milliseconds)
    {
        if (isAndroid())
            vibrator.Call("vibrate", milliseconds);
        else
            Handheld.Vibrate();
    }

    /// 

    /// 模式震動
    /// 重覆
    /// 
    /// 
    /// 
    public static void Vibrate(long[] pattern, int repeat)
    {
        if (isAndroid())
            vibrator.Call("vibrate", pattern, repeat);
        else
            Handheld.Vibrate();
    }

    /// 

    /// 判斷是否震動器
    /// 
    /// 
    public static bool HasVibrator()
    {
        return isAndroid();
    }

    /// 

    /// 取消
    /// 
    public static void Cancel()
    {
        if (isAndroid())
            vibrator.Call("cancel");
    }
}

 

文章標籤

Xauxas 發表在 痞客邦 留言(0) 人氣()

棋靈王這部動漫可能有點久了,但是動漫歌曲,還不錯的聽的。

鋼琴譜發佈有點時間了,為了刷一下部落格的存在感....我在寫到此部落格吧。

 

YouTube 歡迎各位來聆聽

樂譜下載位置

 

文章標籤

Xauxas 發表在 痞客邦 留言(0) 人氣()